@adaptabletools/adaptable 20.0.5 → 20.0.7-canary.0

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 (37) hide show
  1. package/base.css +20 -0
  2. package/base.css.map +1 -1
  3. package/index.css +16 -0
  4. package/index.css.map +1 -1
  5. package/package.json +1 -1
  6. package/src/AdaptableOptions/ColumnOptions.d.ts +173 -2
  7. package/src/AdaptableState/Common/AggregationColumns.d.ts +8 -1
  8. package/src/AdaptableState/LayoutState.d.ts +12 -0
  9. package/src/Api/Implementation/ColumnApiImpl.d.ts +1 -0
  10. package/src/Api/Implementation/ColumnApiImpl.js +11 -1
  11. package/src/Api/Implementation/LayoutHelpers.js +25 -2
  12. package/src/Api/Internal/ColumnInternalApi.d.ts +3 -1
  13. package/src/Api/Internal/ColumnInternalApi.js +201 -0
  14. package/src/Utilities/Constants/GeneralConstants.d.ts +1 -0
  15. package/src/Utilities/Constants/GeneralConstants.js +1 -0
  16. package/src/Utilities/Extensions/StringExtensions.js +11 -3
  17. package/src/Utilities/adaptableOverrideCheck.d.ts +2 -0
  18. package/src/Utilities/adaptableOverrideCheck.js +8 -0
  19. package/src/agGrid/AdaptableAgGrid.js +29 -0
  20. package/src/agGrid/AgGridAdapter.js +1 -0
  21. package/src/agGrid/AgGridColumnAdapter.d.ts +1 -1
  22. package/src/agGrid/AgGridColumnAdapter.js +7 -13
  23. package/src/components/Select/Select.js +3 -3
  24. package/src/env.js +2 -2
  25. package/src/layout-manager/src/LayoutManagerModel.d.ts +23 -20
  26. package/src/layout-manager/src/destructurePivotColumnId.d.ts +10 -0
  27. package/src/layout-manager/src/destructurePivotColumnId.js +80 -0
  28. package/src/layout-manager/src/index.d.ts +5 -0
  29. package/src/layout-manager/src/index.js +168 -2
  30. package/src/layout-manager/src/isPivotGroupTotalColumn.d.ts +2 -0
  31. package/src/layout-manager/src/isPivotGroupTotalColumn.js +5 -0
  32. package/src/layout-manager/src/isPivotTotalColumn.d.ts +2 -0
  33. package/src/layout-manager/src/isPivotTotalColumn.js +3 -0
  34. package/src/layout-manager/src/normalizeLayoutModel.js +3 -0
  35. package/src/metamodel/adaptable.metamodel.d.ts +12 -4
  36. package/src/metamodel/adaptable.metamodel.js +1 -1
  37. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -1,5 +1,5 @@
1
1
  import { ApiBase } from '../Implementation/ApiBase';
2
- import { Column, IRowNode } from 'ag-grid-enterprise';
2
+ import { Column, HeaderValueGetterParams, IRowNode } from 'ag-grid-enterprise';
3
3
  import { CustomSort } from '../../AdaptableState/CustomSortState';
4
4
  import { ColumnValuesComparer } from '../../AdaptableOptions/CustomSortOptions';
5
5
  import { AdaptableColumn } from '../../types';
@@ -31,4 +31,6 @@ export declare class ColumnInternalApi extends ApiBase {
31
31
  getAgGridColumnForAdaptableColumn(columnId: string): Column;
32
32
  getActiveColumnComparator(columnId: string, customSort?: CustomSort, customSortComparer?: ColumnValuesComparer): (valueA: any, valueB: any, nodeA?: IRowNode, nodeB?: IRowNode, isInverted?: boolean) => number | undefined;
33
33
  isSpecialColumn(columnId: string, column?: AdaptableColumn): boolean;
34
+ getColumnHeaderName(params: HeaderValueGetterParams): string;
35
+ private buildColumnHeaderContext;
34
36
  }
@@ -2,6 +2,10 @@ import { ApiBase } from '../Implementation/ApiBase';
2
2
  import { AG_GRID_GROUPED_COLUMN } from '../../Utilities/Constants/GeneralConstants';
3
3
  import uniq from 'lodash/uniq';
4
4
  import StringExtensions from '../../Utilities/Extensions/StringExtensions';
5
+ import { isPivotGrandTotalColumn, isPivotResultColumn } from '../Implementation/ColumnApiImpl';
6
+ import { destructurePivotColumnId } from '../../layout-manager/src/destructurePivotColumnId';
7
+ import { isPivotGroupTotalColumn } from '../../layout-manager/src/isPivotGroupTotalColumn';
8
+ import { isPivotTotalColumn } from '../../layout-manager/src/isPivotTotalColumn';
5
9
  export function getAutoRowGroupColumnIdFor(columnId) {
6
10
  return `${AG_GRID_GROUPED_COLUMN}-${columnId}`;
7
11
  }
@@ -81,4 +85,201 @@ export class ColumnInternalApi extends ApiBase {
81
85
  this.getColumnApi().isActionColumn(columnId) ||
82
86
  this.getColumnApi().isFdc3Column(columnId));
83
87
  }
88
+ getColumnHeaderName(params) {
89
+ // this is the same object, but casting it makes it easier to work with
90
+ const isColumn = !params.columnGroup;
91
+ const columnParams = params;
92
+ const isColumnGroup = !!params.columnGroup;
93
+ const columnGroupParams = params;
94
+ const defaultHeaderName = params.colDef?.headerName ??
95
+ (isColumn ? StringExtensions.CamelCaseToHumanText(columnParams.colDef?.field) : '') ??
96
+ '';
97
+ // for now we override ONLY the header names
98
+ if (params.location !== 'header') {
99
+ return defaultHeaderName;
100
+ }
101
+ // 1. Layout specific header has the highest priority
102
+ const layoutSpecificCustomHeader = this.getLayoutApi().getCurrentLayout().ColumnHeaders?.[isColumn ? columnParams.column.getColId() : columnGroupParams.columnGroup.getGroupId()];
103
+ if (layoutSpecificCustomHeader) {
104
+ return layoutSpecificCustomHeader;
105
+ }
106
+ // 2. check for custom ColumnOptions.columnHeader
107
+ if (typeof this.getColumnOptions().columnHeader === 'function') {
108
+ const columnHeaderContext = this.buildColumnHeaderContext(params, defaultHeaderName);
109
+ if (columnHeaderContext === 'skip') {
110
+ return defaultHeaderName;
111
+ }
112
+ const customHeader = this.getColumnOptions().columnHeader(columnHeaderContext);
113
+ return customHeader;
114
+ }
115
+ // 3. fallback to default header name
116
+ return defaultHeaderName;
117
+ }
118
+ buildColumnHeaderContext(params, defaultHeaderName) {
119
+ const currentLayoutType = this.getLayoutApi().isCurrentLayoutPivot() ? 'pivot' : 'table';
120
+ const currentLayout = this.getLayoutApi().getCurrentLayout();
121
+ const baseContext = {
122
+ ...this.getAdaptableApi().internalApi.buildBaseContext(),
123
+ defaultHeaderName,
124
+ currentLayout,
125
+ currentLayoutName: currentLayout.Name,
126
+ currentLayoutType: currentLayoutType,
127
+ };
128
+ // makes it easier to work with
129
+ const currentTableLayout = currentLayout;
130
+ const currentPivotLayout = currentLayout;
131
+ if (params.column?.getColId() === AG_GRID_GROUPED_COLUMN) {
132
+ const columnType = 'autoGroupColumn';
133
+ return {
134
+ ...baseContext,
135
+ columnType,
136
+ columnId: params.column.getColId(),
137
+ groupedColumnIds: currentLayoutType === 'table'
138
+ ? currentTableLayout.RowGroupedColumns ?? []
139
+ : currentPivotLayout.PivotGroupedColumns ?? [],
140
+ };
141
+ }
142
+ if (params.column?.getColId().startsWith(`${AG_GRID_GROUPED_COLUMN}-`)) {
143
+ const columnType = 'groupColumn';
144
+ const columnId = params.column.getColId();
145
+ // remove `${AG_GRID_GROUPED_COLUMN}-` from beginning of columnId
146
+ const groupColumnId = columnId.substring(`${AG_GRID_GROUPED_COLUMN}-`.length);
147
+ return {
148
+ ...baseContext,
149
+ columnType,
150
+ columnId,
151
+ groupColumnId,
152
+ };
153
+ }
154
+ if (baseContext.currentLayoutType === 'table') {
155
+ if (params.columnGroup) {
156
+ const columnType = 'tableColumnGroup';
157
+ if (!params.colDef?.children) {
158
+ // AG Grid created virtual column groups for all columns
159
+ // we want to skip those
160
+ return 'skip';
161
+ }
162
+ return {
163
+ ...baseContext,
164
+ columnType,
165
+ groupId: params.columnGroup?.getGroupId(),
166
+ childrenColumnIds: params.columnGroup
167
+ ?.getChildren()
168
+ .map((col) => {
169
+ if (col.isColumn) {
170
+ return col.getColId();
171
+ }
172
+ })
173
+ .filter(Boolean),
174
+ state: params.columnGroup?.isExpandable() && !params.columnGroup?.isExpanded()
175
+ ? 'collapsed'
176
+ : 'expanded',
177
+ };
178
+ }
179
+ if (params.column) {
180
+ const columnType = 'tableColumn';
181
+ return {
182
+ ...baseContext,
183
+ columnType,
184
+ columnId: params.column?.getColId(),
185
+ aggregation: params.column.getAggFunc(),
186
+ };
187
+ }
188
+ }
189
+ if (baseContext.currentLayoutType === 'pivot') {
190
+ if (params.columnGroup) {
191
+ if (!params.colDef?.pivotKeys) {
192
+ // we might have user defined colGroups, but we are not interested in them in pivot mode
193
+ return 'skip';
194
+ }
195
+ const columnType = 'pivotColumnGroup';
196
+ return {
197
+ ...baseContext,
198
+ columnType,
199
+ groupId: params.columnGroup?.getGroupId(),
200
+ pivotKeys: params.colDef.pivotKeys,
201
+ state: params.columnGroup?.isExpandable() && !params.columnGroup?.isExpanded()
202
+ ? 'collapsed'
203
+ : 'expanded',
204
+ };
205
+ }
206
+ if (params.column) {
207
+ let columnId = params.column.getColId();
208
+ if (isPivotGrandTotalColumn(columnId)) {
209
+ const columnType = 'pivotGrandTotal';
210
+ const pivotValueCol = params.colDef.pivotValueColumn;
211
+ const aggregatedColumnId = pivotValueCol?.getColId();
212
+ const currentLayoutAggCols = currentPivotLayout.PivotAggregationColumns?.map((col) => col.ColumnId);
213
+ if (!currentLayoutAggCols?.includes(aggregatedColumnId)) {
214
+ // this column is not an aggregation column
215
+ return 'skip';
216
+ }
217
+ return {
218
+ ...baseContext,
219
+ columnType,
220
+ aggregatedColumnId,
221
+ aggregation: pivotValueCol.getAggFunc(),
222
+ };
223
+ }
224
+ if (isPivotGroupTotalColumn(params.colDef)) {
225
+ const columnType = 'pivotGroupTotal';
226
+ const pivotColInfo = destructurePivotColumnId(params.colDef, {
227
+ pivotColIds: currentPivotLayout.PivotColumns,
228
+ aggColIds: currentPivotLayout.PivotAggregationColumns.map((col) => col.ColumnId),
229
+ }, (message) => this.logWarn(message));
230
+ if (pivotColInfo === '!unknown!') {
231
+ return 'skip';
232
+ }
233
+ const pivotKey = pivotColInfo.pivotKeys[pivotColInfo.pivotKeys.length - 1];
234
+ return {
235
+ ...baseContext,
236
+ columnType,
237
+ pivotKey,
238
+ pivotColumnId: pivotColInfo.pivotColumnId,
239
+ aggregation: params.colDef?.pivotValueColumn?.getAggFunc(),
240
+ };
241
+ }
242
+ if (isPivotTotalColumn(params.colDef)) {
243
+ const columnType = 'pivotAggregationTotal';
244
+ const pivotValueCol = params.colDef.pivotValueColumn;
245
+ const pivotColInfo = destructurePivotColumnId(params.colDef, {
246
+ pivotColIds: currentPivotLayout.PivotColumns,
247
+ aggColIds: currentPivotLayout.PivotAggregationColumns.map((col) => col.ColumnId),
248
+ }, (message) => this.logWarn(message));
249
+ if (pivotColInfo === '!unknown!') {
250
+ return 'skip';
251
+ }
252
+ const pivotKey = pivotColInfo.pivotKeys[pivotColInfo.pivotKeys.length - 1];
253
+ return {
254
+ ...baseContext,
255
+ columnType,
256
+ aggregatedColumnId: pivotValueCol?.getColId(),
257
+ aggregation: pivotValueCol.getAggFunc(),
258
+ pivotColumnId: pivotColInfo.pivotColumnId,
259
+ pivotKey,
260
+ };
261
+ }
262
+ if (isPivotResultColumn(columnId)) {
263
+ const columnType = 'pivotAggregationColumn';
264
+ const pivotValueCol = params.colDef.pivotValueColumn;
265
+ const aggregatedColumnId = pivotValueCol?.getColId();
266
+ const currentLayoutAggCols = currentPivotLayout.PivotAggregationColumns?.map((col) => col.ColumnId);
267
+ if (!currentLayoutAggCols?.includes(aggregatedColumnId)) {
268
+ // this column is not an aggregation column
269
+ return 'skip';
270
+ }
271
+ return {
272
+ ...baseContext,
273
+ columnType,
274
+ columnId,
275
+ pivotKeys: params.colDef.pivotKeys,
276
+ aggregatedColumnId,
277
+ aggregation: pivotValueCol.getAggFunc(),
278
+ };
279
+ }
280
+ }
281
+ }
282
+ // if nothing matched, we skip this column[group]
283
+ return 'skip';
284
+ }
84
285
  }
@@ -24,6 +24,7 @@ export declare const GROUP_PATH_SEPARATOR: string;
24
24
  export declare const AG_GRID_GROUPED_COLUMN: string;
25
25
  export declare const AG_GRID_SELECTION_COLUMN: string;
26
26
  export declare const AG_GRID_PIVOT_COLUMN: string;
27
+ export declare const AG_GRID_PIVOT_GRAND_TOTAL_COLUMN: string;
27
28
  export declare const AG_GRID_CHART_WINDOW = "AG Grid Window";
28
29
  export declare const ADAPTABLE_FDC3_ACTION_COLUMN_FRIENDLY_NAME = "(FDC3ActionColumn)";
29
30
  export declare const DEFAULT_DATE_FORMAT_PATTERN = "dd-MM-yyyy";
@@ -23,6 +23,7 @@ export const GROUP_PATH_SEPARATOR = '/';
23
23
  export const AG_GRID_GROUPED_COLUMN = 'ag-Grid-AutoColumn';
24
24
  export const AG_GRID_SELECTION_COLUMN = 'ag-Grid-SelectionColumn';
25
25
  export const AG_GRID_PIVOT_COLUMN = 'pivot_';
26
+ export const AG_GRID_PIVOT_GRAND_TOTAL_COLUMN = 'PivotRowTotal_pivot_';
26
27
  export const AG_GRID_CHART_WINDOW = 'AG Grid Window';
27
28
  export const ADAPTABLE_FDC3_ACTION_COLUMN_FRIENDLY_NAME = '(FDC3ActionColumn)';
28
29
  // FIXME AFL - load this from DateInputOptions
@@ -23,13 +23,21 @@ export function IsNullOrEmptyOrWhiteSpace(stringToCheck) {
23
23
  export function IsNotNullOrEmptyOrWhiteSpace(stringToCheck) {
24
24
  return !IsNullOrEmptyOrWhiteSpace(stringToCheck);
25
25
  }
26
- // from https://stackoverflow.com/questions/15369566/putting-space-in-camel-case-string-using-regular-expression
26
+ // clone of A Grid's implementation
27
+ // https://github.com/ag-grid/ag-grid/blob/a5c3d9f56350271ab7e8d42d72aaf5314672719a/packages/ag-grid-community/src/columns/columnNameService.ts#L14
27
28
  export function CamelCaseToHumanText(camelCase) {
28
29
  if (!camelCase || camelCase == null) {
29
30
  return null;
30
31
  }
31
- const rex = /([A-Z])([A-Z])([a-z])|([a-z])([A-Z])/g;
32
- const words = camelCase.replace(rex, '$1$4 $2$3$5').replace('.', ' ').split(' ');
32
+ // either split on a lowercase followed by uppercase ie asHereTo -> as Here To
33
+ const rex = /([a-z])([A-Z])/g;
34
+ // or starts with uppercase and we take all expect the last which is assumed to be part of next word if followed by lowercase HEREToThere -> HERE To There
35
+ const rexCaps = /([A-Z]+)([A-Z])([a-z])/g;
36
+ const words = camelCase
37
+ .replace(rex, '$1 $2')
38
+ .replace(rexCaps, '$1 $2$3')
39
+ .replace(/\./g, ' ')
40
+ .split(' ');
33
41
  return words
34
42
  .map((word) => word.substring(0, 1).toUpperCase() + (word.length > 1 ? word.substring(1, word.length) : ''))
35
43
  .join(' ');
@@ -0,0 +1,2 @@
1
+ export declare function tagProvidedByAdaptable(fn: any): any;
2
+ export declare function isProvidedByAdaptable(fn: any): boolean;
@@ -0,0 +1,8 @@
1
+ const PROVIDED_BY_ADAPTABLE = Symbol('isProvidedByAdaptable');
2
+ export function tagProvidedByAdaptable(fn) {
3
+ fn[PROVIDED_BY_ADAPTABLE] = true;
4
+ return fn;
5
+ }
6
+ export function isProvidedByAdaptable(fn) {
7
+ return fn && !!fn[PROVIDED_BY_ADAPTABLE];
8
+ }
@@ -97,6 +97,7 @@ import { ACTION_COLUMN_TYPE, CALCULATED_COLUMN_TYPE, FDC3_COLUMN_TYPE, FREE_TEXT
97
97
  import { agGridDataTypeDefinitions } from './agGridDataTypeDefinitions';
98
98
  import { AgGridThemeAdapter } from './AgGridThemeAdapter';
99
99
  import { mapOldTypeToDataType } from '../migration/VersionUpgrade20';
100
+ import { tagProvidedByAdaptable } from '../Utilities/adaptableOverrideCheck';
100
101
  const LocalEventService_Prototype = LocalEventService.prototype;
101
102
  const LocalEventService_dispatchEvent = LocalEventService_Prototype.dispatchEvent;
102
103
  LocalEventService_Prototype.dispatchEvent = function (event) {
@@ -610,6 +611,34 @@ You need to define at least one Layout!`);
610
611
  this.agGridAdapter.setAgGridId(agGridId);
611
612
  return agGridId;
612
613
  });
614
+ /**
615
+ * `defaultColDef`
616
+ */
617
+ this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'defaultColDef', (original_defaultColDef) => {
618
+ if (original_defaultColDef?.headerValueGetter) {
619
+ this.logger.warn(`defaultColDef.headerValueGetter and overrides the Adaptable custom header mechanism! We recommend using a ColumnOptions.tableColumnHeader instead!`);
620
+ return original_defaultColDef;
621
+ }
622
+ const defaultColDef = original_defaultColDef ?? {};
623
+ defaultColDef.headerValueGetter = tagProvidedByAdaptable((params) => {
624
+ return this.api.columnApi.internalApi.getColumnHeaderName(params);
625
+ });
626
+ return defaultColDef;
627
+ });
628
+ /**
629
+ * `defaultColGroupDef`
630
+ */
631
+ this.agGridOptionsService.setGridOptionsProperty(gridOptions, 'defaultColGroupDef', (original_defaultColGroupDef) => {
632
+ if (original_defaultColGroupDef?.headerValueGetter) {
633
+ this.logger.warn(`defaultColGroupDef.headerValueGetter and overrides the Adaptable custom header mechanism! We recommend using a ColumnOptions.tableColumnHeader instead!`);
634
+ return original_defaultColGroupDef;
635
+ }
636
+ const defaultColGroupDef = original_defaultColGroupDef ?? {};
637
+ defaultColGroupDef.headerValueGetter = tagProvidedByAdaptable((params) => {
638
+ return this.api.columnApi.internalApi.getColumnHeaderName(params);
639
+ });
640
+ return defaultColGroupDef;
641
+ });
613
642
  /**
614
643
  * `theme`
615
644
  */
@@ -374,6 +374,7 @@ export class AgGridAdapter {
374
374
  agColumn: agGridColumn,
375
375
  columnGroup: isRealColumnGroup ? ColumnGroup : undefined,
376
376
  displayName: displayName,
377
+ ...this.adaptableApi.internalApi.buildBaseContext(),
377
378
  })
378
379
  : null;
379
380
  friendlyName =
@@ -27,7 +27,7 @@ export declare class AgGridColumnAdapter {
27
27
  private setupColumnAllowedAggFuncs;
28
28
  private setupColumnType;
29
29
  private setupColumnCellDataType;
30
- setupColumnHeader({ col, abColumn }: ColumnSetupInfo): boolean;
30
+ setupColumnHeader({ col, abColumn }: ColumnSetupInfo): void;
31
31
  private setupColumnFilter;
32
32
  setupColumnFloatingFilterTemporarily(initialGridOptions: GridOptions): void;
33
33
  private setupColumnFloatingFilter;
@@ -12,7 +12,8 @@ import Helper from '../Utilities/Helpers/Helper';
12
12
  import { AdaptableNumberEditor, AdaptableReactNumberEditor } from './editors/AdaptableNumberEditor';
13
13
  import { AdaptableDateEditor, AdaptableReactDateEditor } from './editors/AdaptableDateEditor';
14
14
  import { AgGridExportAdapter } from './AgGridExportAdapter';
15
- import { AdaptableHelper, } from '../Utilities/Helpers/AdaptableHelper';
15
+ import { AdaptableHelper } from '../Utilities/Helpers/AdaptableHelper';
16
+ import { isProvidedByAdaptable } from '../Utilities/adaptableOverrideCheck';
16
17
  export function getEditorForColumnDataType(columnDataType, variant) {
17
18
  if (columnDataType === 'number') {
18
19
  return variant === 'react' ? AdaptableReactNumberEditor : AdaptableNumberEditor;
@@ -371,19 +372,12 @@ export class AgGridColumnAdapter {
371
372
  });
372
373
  }
373
374
  setupColumnHeader({ col, abColumn }) {
374
- const previousColumnHeader = col?.getColDef()?.headerName;
375
- this.setColDefProperty(col, 'headerName', (userHeaderName) => {
376
- // set the default to the AG Grid provided values
377
- // from https://github.com/ag-grid/ag-grid/blob/v26.1.0/community-modules/core/src/ts/columns/columnModel.ts#L2515
378
- let resultHeaderName = userHeaderName ?? StringExtensions.CamelCaseToHumanText(col.getColDef().field);
379
- const layoutCustomHeader = this.adaptableApi.layoutApi.getCurrentLayout().ColumnHeaders?.[col.getColId()];
380
- if (layoutCustomHeader) {
381
- resultHeaderName = layoutCustomHeader;
382
- }
383
- return resultHeaderName;
375
+ this.setColDefProperty(col, 'headerValueGetter', (original_headerValueGetter) => {
376
+ if (!isProvidedByAdaptable(original_headerValueGetter)) {
377
+ this.adaptableApi.logWarn(`colDef.headerValueGetter is defined for column '${col.getColId()}', and overrides the Adaptable custom header mechanism! We recommend using a ColumnOptions.tableColumnHeader instead!`);
378
+ }
379
+ return original_headerValueGetter;
384
380
  });
385
- const newColumnHeader = col?.getColDef()?.headerName;
386
- return previousColumnHeader !== newColumnHeader;
387
381
  }
388
382
  setupColumnFilter({ col, colDef }) {
389
383
  this.setColDefProperty(col, 'filter', () => {
@@ -29,7 +29,7 @@ const INFINITE_COLUMNS_WITH_CHECKBOX = {
29
29
  resizable: false,
30
30
  defaultSortable: false,
31
31
  renderSelectionCheckBox: ({ renderBag }) => {
32
- return (React.createElement(Box, { display: 'inline-block', style: checkboxStyle }, renderBag.selectionCheckBox));
32
+ return renderBag.selectionCheckBox;
33
33
  },
34
34
  renderHeader: (headerParams) => {
35
35
  return (React.createElement(React.Fragment, null,
@@ -149,7 +149,7 @@ export const Select = function (props) {
149
149
  placeholder: props.placeholder,
150
150
  });
151
151
  const title = typeof customRenderValue === 'string' ? customRenderValue : '';
152
- children = customRenderValue ? (React.createElement(Box, { display: 'flex', flexDirection: 'row', flex: 1, flexWrap: 'nowrap', alignItems: 'center', overflow: 'hidden' },
152
+ children = customRenderValue ? (React.createElement(Box, { display: 'flex', flexDirection: 'row', flex: 1, flexWrap: 'nowrap', alignItems: 'center', overflow: 'hidden', height: '100%' },
153
153
  React.createElement("span", { title: title, "data-name": "multi-value-text", style: {
154
154
  flex: '0 1 auto',
155
155
  appearance: 'none',
@@ -466,7 +466,7 @@ export const Select = function (props) {
466
466
  return {
467
467
  ...baseStyle,
468
468
  ...commonStyles(state), // height: 30,
469
- minHeight: props.size === 'small' ? 0 : 32,
469
+ minHeight: props.size === 'small' ? 0 : '100%',
470
470
  boxShadow: state.isFocused ? 'var(--ab-cmp-select-focused__box-shadow)' : 'none',
471
471
  outline: state.isFocused ? 'var(--ab-cmp-select-focused__outline)' : 'none',
472
472
  border: 'var(--ab-cmp-select__border)',
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: 1744964803967 || Date.now(),
4
- VERSION: "20.0.5" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1745347655771 || Date.now(),
4
+ VERSION: "20.0.7-canary.0" || '--current-version--',
5
5
  };
@@ -62,26 +62,17 @@ export type ColumnAggregationModel = {
62
62
  aggFunc: string | true;
63
63
  weightedColumnId?: string;
64
64
  };
65
- export type AggregationColumnsModel = {
65
+ export type AggregationColumnsModelItem = {
66
66
  ColumnId: string;
67
67
  AggFunc: ColumnAggregationModel;
68
- }[];
69
- type RowSummaryPosition = 'Top' | 'Bottom';
70
- export interface RowSummaryModel {
71
- /**
72
- * Where Row Summary appears - 'Top' or 'Bottom'
73
- */
74
- Position?: RowSummaryPosition;
75
- /**
76
- * Map of Columns with Summary Expressions
77
- */
78
- ColumnsMap: Record<string, string>;
79
- /**
80
- * Evaluates only currently filtered rows in the summary
81
- * @defaultValue true
82
- */
83
- IncludeOnlyFilteredRows?: boolean;
84
- }
68
+ };
69
+ export type AggregationColumnsModel = AggregationColumnsModelItem[];
70
+ export type PivotAggregationColumnsModel = (AggregationColumnsModelItem & {
71
+ TotalColumn?: boolean | 'before' | 'after' | {
72
+ PivotColumnId: string;
73
+ ShowTotal?: boolean | 'before' | 'after';
74
+ }[];
75
+ })[];
85
76
  export interface TableLayoutModel extends BaseLayoutModel {
86
77
  TableColumns: string[];
87
78
  /**
@@ -96,6 +87,7 @@ export interface TableLayoutModel extends BaseLayoutModel {
96
87
  * @defaultValue 'single'
97
88
  */
98
89
  RowGroupDisplayType?: 'single' | 'multi';
90
+ PivotAggregationColumns?: never;
99
91
  PivotColumns?: never;
100
92
  PivotGroupedColumns?: never;
101
93
  PivotExpandLevel?: never;
@@ -110,13 +102,24 @@ export interface PivotLayoutModel extends BaseLayoutModel {
110
102
  /**
111
103
  * Columns showing aggregated values in Group Rows; 1st value in record is Column name, 2nd is either aggfunc (e.g. sum, avg etc.) or 'true' (to use default aggfunc)
112
104
  */
113
- PivotAggregationColumns?: AggregationColumnsModel;
105
+ PivotAggregationColumns?: PivotAggregationColumnsModel;
114
106
  TableAggregationColumns?: never;
115
107
  /**
116
108
  * Columns which are row-grouped when the Layout is applied
117
109
  */
118
110
  PivotGroupedColumns?: string[];
119
111
  RowGroupedColumns?: never;
112
+ /**
113
+ * Display Grand Total Row at the top or bottom of the Pivot Table
114
+ */
115
+ GrandTotalRow?: 'top' | 'bottom' | boolean;
116
+ /**
117
+ * Display Total of all Pivot Columns before or after the Pivot Columns
118
+ */
119
+ GrandTotalColumn?: 'before' | 'after' | boolean;
120
+ /**
121
+ * Display automatically calculated Totals within EACH Pivot Column Group, in the position specified
122
+ */
123
+ PivotGroupTotalColumn?: 'before' | 'after' | boolean;
120
124
  }
121
125
  export type LayoutModel = TableLayoutModel | PivotLayoutModel;
122
- export {};
@@ -0,0 +1,10 @@
1
+ import { ColDef } from 'ag-grid-enterprise';
2
+ export declare function destructurePivotColumnId(colDef: ColDef, currentModel: {
3
+ pivotColIds: string[];
4
+ aggColIds: string[];
5
+ }, logWarning: (message: string) => void): '!unknown!' | {
6
+ pivotColumnIds: string[];
7
+ pivotKeys: string[];
8
+ pivotColumnId: string;
9
+ aggregationColumnId?: string;
10
+ };
@@ -0,0 +1,80 @@
1
+ // supports only pivotTotalColumns (aggregation total) and pivotGroupTotal
2
+ // AG Grid builds the ID as: `pivot_${pivotCols.join('-')}_${pivotKeys.join('-')}_${measureColumnId}`
3
+ // see https://github.com/ag-grid/ag-grid/blob/e0cfe533b55b75cdc148cdfb1a4e977731dc0712/packages/ag-grid-enterprise/src/pivot/pivotColDefService.ts#L454C16-L454C88
4
+ export function destructurePivotColumnId(colDef, currentModel, logWarning) {
5
+ const { colId } = colDef;
6
+ // Basic validation
7
+ if (!colId?.startsWith('pivot_')) {
8
+ logWarning(`Column id must start with 'pivot_': ${colId}`);
9
+ return '!unknown!';
10
+ }
11
+ const hasSpecialChars = (arr) => arr.some((str) => str.includes('-') || str.includes('_'));
12
+ // AG Grid uses _ and - as delimiters
13
+ // if we have these special characters in the column IDs, we need to parse them differently
14
+ const colIdsOrKeysContainSpecialChars = hasSpecialChars(currentModel.pivotColIds) ||
15
+ hasSpecialChars(currentModel.aggColIds) ||
16
+ hasSpecialChars(colDef.pivotKeys || []);
17
+ // Fast path - no special characters
18
+ if (!colIdsOrKeysContainSpecialChars) {
19
+ // Split by underscore to get 4 parts
20
+ const parts = colId.split('_');
21
+ if (parts.length !== 4) {
22
+ logWarning(`Unsupported format of pivot total column id: ${colId}`);
23
+ return '!unknown!';
24
+ }
25
+ const [_pivotPrefix, pivotColsTxt, pivotKeysTxt, aggregationColumnId] = parts;
26
+ const pivotColumnIds = pivotColsTxt.split('-');
27
+ const pivotKeys = pivotKeysTxt.split('-');
28
+ const pivotColumnId = pivotColumnIds[pivotKeys.length - 1];
29
+ return {
30
+ pivotColumnIds,
31
+ pivotKeys,
32
+ pivotColumnId,
33
+ aggregationColumnId: aggregationColumnId !== '' ? aggregationColumnId : undefined,
34
+ };
35
+ }
36
+ // the complex path, where we have to handle the special characters
37
+ // Remove 'pivot_' prefix
38
+ const withoutPrefix = colId.slice(6);
39
+ // Check if it's a pivot group total
40
+ const isPivotGroupTotal = withoutPrefix.endsWith('_');
41
+ // Get pivot keys from colDef (more reliable than string parsing)
42
+ const pivotKeys = colDef.pivotKeys || [];
43
+ if (isPivotGroupTotal) {
44
+ // Remove trailing underscore for pivot group totals
45
+ const content = withoutPrefix.slice(0, -1);
46
+ // The remaining content should be the pivot columns
47
+ const pivotColumnIds = currentModel.pivotColIds.filter((id) => content.includes(id));
48
+ if (!pivotColumnIds.length) {
49
+ logWarning(`Could not identify pivot columns in: ${content}`);
50
+ return '!unknown!';
51
+ }
52
+ return {
53
+ pivotColumnIds,
54
+ pivotKeys,
55
+ pivotColumnId: pivotColumnIds[pivotKeys.length],
56
+ };
57
+ }
58
+ // For regular pivot columns, work backwards to find aggregation column
59
+ const parts = withoutPrefix.split('_');
60
+ const lastPart = parts[parts.length - 1];
61
+ // Find the longest matching aggregation column id from the end
62
+ const aggregationColumnId = currentModel.aggColIds.find((aggId) => lastPart.endsWith(aggId));
63
+ if (!aggregationColumnId) {
64
+ logWarning(`Could not identify aggregation column in: ${lastPart}`);
65
+ return '!unknown!';
66
+ }
67
+ // Remove aggregation part and get pivot columns
68
+ const withoutAgg = withoutPrefix.slice(0, -(aggregationColumnId.length + 1));
69
+ const pivotColumnIds = currentModel.pivotColIds.filter((id) => withoutAgg.includes(id));
70
+ if (!pivotColumnIds.length) {
71
+ logWarning(`Could not identify pivot columns in: ${withoutAgg}`);
72
+ return '!unknown!';
73
+ }
74
+ return {
75
+ pivotColumnIds,
76
+ pivotKeys,
77
+ pivotColumnId: pivotColumnIds[pivotKeys.length - 1],
78
+ aggregationColumnId,
79
+ };
80
+ }
@@ -69,7 +69,12 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
69
69
  private computeColumnOrderAndVisibility;
70
70
  autoSizeColumns(columnIds?: string[]): false | string[];
71
71
  private applyPivotLayout;
72
+ applyPivotTotals(layout: PivotLayoutModel): void;
72
73
  applyPivotExpandLevel(layout: PivotLayoutModel): void;
73
74
  private withSuppressColumnAnimation;
75
+ private setupPivotTotals;
76
+ private isPivotRowTotalColDef;
77
+ private patchPivotTotalColumn;
78
+ private getPivotTotalColumnConfig;
74
79
  }
75
80
  export {};