@adaptabletools/adaptable-cjs 21.0.5 → 21.0.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptabletools/adaptable-cjs",
3
- "version": "21.0.5",
3
+ "version": "21.0.7",
4
4
  "description": "Powerful data-agnostic HTML5 AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
5
5
  "keywords": [
6
6
  "web-components",
@@ -11,7 +11,7 @@ export interface DateInputOptions {
11
11
  /**
12
12
  * Format string for formatting date input field
13
13
  *
14
- * @defaultValue 'yyyy-MM-dd'
14
+ * @defaultValue 'yyyy-MM-dd' (ISO 8601 format)
15
15
  */
16
16
  dateFormat?: string;
17
17
  /**
@@ -35,6 +35,23 @@ exports.layoutModelToLayoutState = layoutModelToLayoutState;
35
35
  function cleanupAdaptableObjectPrimitives(layout) {
36
36
  const l = layout;
37
37
  for (const key in l) {
38
+ if (key === 'ColumnFilters') {
39
+ // we don't want to cleanup ColumnFilters
40
+ // as we rely on the Uuids for identifying the filters
41
+ if (Array.isArray(l[key])) {
42
+ l[key].forEach((item) => {
43
+ if (typeof item === 'object') {
44
+ // but we do want to cleanup further down - eg: predicates in the filter
45
+ for (const k in item) {
46
+ if (typeof item[k] === 'object') {
47
+ (0, AdaptableHelper_1.removeAdaptableObjectPrimitivesInlineDeep)(item[k]);
48
+ }
49
+ }
50
+ }
51
+ });
52
+ }
53
+ continue;
54
+ }
38
55
  if (typeof l[key] === 'object') {
39
56
  (0, AdaptableHelper_1.removeAdaptableObjectPrimitivesInlineDeep)(l[key]);
40
57
  }
@@ -372,9 +389,9 @@ const tableLayoutModelToTableLayout = (layoutModel) => {
372
389
  if (layoutModel.Ignore_Metadata) {
373
390
  tableLayout.Metadata = layoutModel.Ignore_Metadata;
374
391
  }
375
- if (layoutModel.RowGroupDisplayType) {
376
- tableLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType;
377
- }
392
+ // if (layoutModel.RowGroupDisplayType) {
393
+ tableLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType ?? 'single';
394
+ // }
378
395
  if (layoutModel.RowGroupedColumns) {
379
396
  tableLayout.RowGroupedColumns = layoutModel.RowGroupedColumns;
380
397
  }
@@ -529,9 +546,9 @@ const pivotLayoutModelToPivotLayout = (layoutModel) => {
529
546
  pivotLayout.ColumnGroupValues.ExceptionGroupKeys = layoutModel.ColumnGroupValues.Values;
530
547
  }
531
548
  }
532
- if (layoutModel.RowGroupDisplayType) {
533
- pivotLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType;
534
- }
549
+ // if (layoutModel.RowGroupDisplayType) {
550
+ pivotLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType ?? 'single';
551
+ // }
535
552
  return pivotLayout;
536
553
  };
537
554
  exports.pivotLayoutModelToPivotLayout = pivotLayoutModelToPivotLayout;
@@ -123,4 +123,5 @@ export declare class AdaptableInternalApi extends ApiBase {
123
123
  findAdaptableObjectsByLookupCriteria<T extends AdaptableObjectWithScope>({ scope, tag, ids }: AdaptableObjectLookupCriteria, specificAdaptableObjects: T[]): T[];
124
124
  buildBaseContext(): BaseContext;
125
125
  setCellSummaryInfo(cellSummaryInfo: CellSummmaryInfo): void;
126
+ parseDateValue(dateValue: string | Date | number): Date | undefined;
126
127
  }
@@ -9,6 +9,7 @@ const StringExtensions_1 = tslib_1.__importDefault(require("../../Utilities/Exte
9
9
  const GeneralConstants_1 = require("../../Utilities/Constants/GeneralConstants");
10
10
  const waitForCondition_1 = require("../../Utilities/waitForCondition");
11
11
  const Icon_1 = require("../../components/Icon");
12
+ const DateHelper_1 = require("../../Utilities/Helpers/DateHelper");
12
13
  class AdaptableInternalApi extends ApiBase_1.ApiBase {
13
14
  getInternalState() {
14
15
  return this.getAdaptableState().Internal;
@@ -443,5 +444,13 @@ class AdaptableInternalApi extends ApiBase_1.ApiBase {
443
444
  setCellSummaryInfo(cellSummaryInfo) {
444
445
  this.dispatchAction(InternalRedux.SetCellSummaryInfo(cellSummaryInfo));
445
446
  }
447
+ parseDateValue(dateValue) {
448
+ const dateFormat = this.getUserInterfaceOptions().dateInputOptions.dateFormat;
449
+ if (dateFormat === 'yyyy-MM-dd') {
450
+ // if the format is ISO, we don't pass it so that we use the date-fns `parseISO` which is more robust
451
+ return (0, DateHelper_1.parseDateValue)(dateValue);
452
+ }
453
+ return (0, DateHelper_1.parseDateValue)(dateValue, dateFormat);
454
+ }
446
455
  }
447
456
  exports.AdaptableInternalApi = AdaptableInternalApi;
@@ -1,7 +1,5 @@
1
1
  import { ApiBase } from '../Implementation/ApiBase';
2
- import { ColDef, Column, HeaderValueGetterParams, IRowNode } from 'ag-grid-enterprise';
3
- import { CustomSort } from '../../AdaptableState/CustomSortState';
4
- import { ColumnValuesComparer } from '../../AdaptableOptions/CustomSortOptions';
2
+ import { ColDef, Column, HeaderValueGetterParams } from 'ag-grid-enterprise';
5
3
  import { AdaptableColumn, AdaptableColumnDataType } from '../../types';
6
4
  export declare function getAutoRowGroupColumnIdFor(columnId: string): string;
7
5
  export declare class ColumnInternalApi extends ApiBase {
@@ -29,7 +27,6 @@ export declare class ColumnInternalApi extends ApiBase {
29
27
  * @param columnId columnId to look up
30
28
  */
31
29
  getAgGridColumnForAdaptableColumn(columnId: string): Column;
32
- getActiveColumnComparator(columnId: string, customSort?: CustomSort, customSortComparer?: ColumnValuesComparer): (valueA: any, valueB: any, nodeA?: IRowNode, nodeB?: IRowNode, isInverted?: boolean) => number | undefined;
33
30
  isSpecialColumn(columnId: string, column?: AdaptableColumn): boolean;
34
31
  getColumnHeaderName(params: HeaderValueGetterParams): string;
35
32
  private buildColumnHeaderContext;
@@ -69,18 +69,6 @@ class ColumnInternalApi extends ApiBase_1.ApiBase {
69
69
  getAgGridColumnForAdaptableColumn(columnId) {
70
70
  return this._adaptable.getAgGridColumnForColumnId(columnId);
71
71
  }
72
- getActiveColumnComparator(columnId, customSort, customSortComparer) {
73
- if ((!customSort || customSort?.IsSuspended) && !customSortComparer) {
74
- // defaults to AG-Grid column definition comparator if no CustomSort is defined&active
75
- const colDefComparator = this._adaptable.agGridColumnAdapter.getUserColDefProperty(columnId, 'comparator');
76
- return colDefComparator;
77
- }
78
- // CustomSort Comparer function takes precedence over CustomSort SortedValues
79
- const comparerFunction = customSortComparer
80
- ? customSortComparer.comparer
81
- : this.getCustomSortApi().internalApi.getDefaultCustomSortComparer(customSort.ColumnId, customSort.SortedValues);
82
- return comparerFunction;
83
- }
84
72
  isSpecialColumn(columnId, column = null) {
85
73
  if (column) {
86
74
  return column.isCalculatedColumn || column.isFreeTextColumn || column.isActionColumn;
@@ -14,6 +14,7 @@ export declare class ExportInternalApi extends ApiBase {
14
14
  setExportInProgress(reportName: ReportNameType, reportFormat: ReportFormatType, exportDestination: ExportDestinationType): void;
15
15
  setExportComplete(): void;
16
16
  isVisualDataExportInProgress(): boolean;
17
+ isExcelExportInProgress(): boolean;
17
18
  createSystemReport(systemReportName: SystemReportName): Report;
18
19
  isSystemReport(reportName: ReportNameType): boolean;
19
20
  isSystemDestination(destination: ExportDestinationType): boolean;
@@ -86,6 +86,9 @@ class ExportInternalApi extends ApiBase_1.ApiBase {
86
86
  isVisualDataExportInProgress() {
87
87
  return this.getAdaptableState().Internal.Export.inProgress?.reportFormat === 'VisualExcel';
88
88
  }
89
+ isExcelExportInProgress() {
90
+ return this.getAdaptableState().Internal.Export.inProgress?.reportFormat === 'Excel';
91
+ }
89
92
  createSystemReport(systemReportName) {
90
93
  switch (systemReportName) {
91
94
  case GeneralConstants_1.ALL_DATA_REPORT:
@@ -8,4 +8,3 @@ export declare const isValueValidDate: (data: any) => boolean;
8
8
  export declare const dateToISO: (date: Date | number | string) => string;
9
9
  export declare const parseToISO: (date: string | Date | number, dateFormat?: string) => string;
10
10
  export declare const parseDateValue: (dateValue: string | Date | number, dateFormat?: string) => Date | undefined;
11
- export declare const parseFilterInputDate: (stringDate: string) => Date;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseFilterInputDate = exports.parseDateValue = exports.parseToISO = exports.dateToISO = exports.isValueValidDate = exports.isValidDate = void 0;
3
+ exports.parseDateValue = exports.parseToISO = exports.dateToISO = exports.isValueValidDate = exports.isValidDate = void 0;
4
4
  const date_fns_1 = require("date-fns");
5
5
  const FormatHelper_1 = require("./FormatHelper");
6
6
  const AdaptableLogger_1 = require("../../agGrid/AdaptableLogger");
@@ -30,6 +30,9 @@ const parseToISO = (date, dateFormat) => {
30
30
  return (0, exports.isValidDate)(dateInstance) ? (0, exports.dateToISO)(dateInstance) : '';
31
31
  };
32
32
  exports.parseToISO = parseToISO;
33
+ // !!!
34
+ // AFL: ideally we should NEVER call directly this method, but use the AdaptableInternalApi.parseDateValue() instead
35
+ // we should refactor this with the first opportunity
33
36
  const parseDateValue = (dateValue, dateFormat) => {
34
37
  if (dateValue == undefined || (typeof dateValue === 'string' && dateValue.trim() === '')) {
35
38
  return undefined;
@@ -37,29 +40,37 @@ const parseDateValue = (dateValue, dateFormat) => {
37
40
  if (dateValue instanceof Date) {
38
41
  return !isNaN(dateValue.getTime()) ? dateValue : undefined;
39
42
  }
40
- let dateInstance;
41
- if (typeof dateValue === 'number') {
42
- dateInstance = new Date(dateValue);
43
- }
44
- else {
45
- // typeof dateValue === 'string'
46
- if (dateFormat) {
47
- dateInstance = (0, date_fns_1.parse)(dateValue, dateFormat, new Date());
43
+ try {
44
+ let dateInstance;
45
+ if (typeof dateValue === 'number') {
46
+ dateInstance = new Date(dateValue);
48
47
  }
49
48
  else {
50
- dateInstance = (0, date_fns_1.parseISO)(dateValue);
49
+ // typeof dateValue === 'string'
50
+ if (dateFormat) {
51
+ dateInstance = (0, date_fns_1.parse)(dateValue, dateFormat, new Date());
52
+ }
53
+ else {
54
+ dateInstance = (0, date_fns_1.parseISO)(dateValue);
55
+ }
56
+ if (!(0, exports.isValidDate)(dateInstance)) {
57
+ // last chance: try to use the native Date.parse(), https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
58
+ dateInstance = new Date(Date.parse(dateValue));
59
+ }
51
60
  }
52
61
  if (!(0, exports.isValidDate)(dateInstance)) {
53
- // last chance: try to use the native Date.parse(), https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
54
- dateInstance = new Date(Date.parse(dateValue));
62
+ AdaptableLogger_1.AdaptableLogger.consoleWarnBase(`Invalid date value "${dateValue}" - cannot be converted to a Date instance. Please make sure you specify adaptableOptions.userInterfaceOptions.dateInputOptions.dateFormat correctly.`);
63
+ dateInstance = undefined;
55
64
  }
65
+ return dateInstance;
56
66
  }
57
- if (!(0, exports.isValidDate)(dateInstance)) {
58
- AdaptableLogger_1.AdaptableLogger.consoleWarnBase(`Invalid date value "${dateValue}" - cannot be converted to a Date instance. Please make sure you specify adaptableOptions.userInterfaceOptions.dateInputOptions.dateFormat correctly.`);
59
- dateInstance = undefined;
67
+ catch (error) {
68
+ const errorMessage = error instanceof Error ? error.message : String(error);
69
+ const errorStack = error instanceof Error ? error.stack : undefined;
70
+ AdaptableLogger_1.AdaptableLogger.consoleErrorBase(`Error parsing date value "${dateValue}": ${errorMessage}`, {
71
+ stack: errorStack,
72
+ originalError: error,
73
+ });
60
74
  }
61
- return dateInstance;
62
75
  };
63
76
  exports.parseDateValue = parseDateValue;
64
- const parseFilterInputDate = (stringDate) => new Date(stringDate);
65
- exports.parseFilterInputDate = parseFilterInputDate;
@@ -35,7 +35,7 @@ class FilterViewPanelComponent extends React.Component {
35
35
  ArrayExtensions_1.ArrayExtensions.IsNotNullOrEmpty(this.props.ColumnFilters) && (React.createElement(AdaptablePopover_1.AdaptablePopover, { popupPadding: 0, className: `ab-${elementType}__Filter__info`, headerText: "", bodyText: [React.createElement(ActiveFiltersPanel_1.ActiveFiltersPanel, null)], useButton: true, showEvent: 'focus', hideEvent: "blur", popoverMinWidth: 400 })),
36
36
  React.createElement(ButtonClear_1.ButtonClear, { "aria-label": 'Clear Filters', className: `ab-${elementType}__Filter__clear`, marginLeft: 1, marginBottom: 0, marginRight: 1, onClick: () => this.onClearFilters(), tooltip: "Clear Filters", disabled: this.props.ColumnFilters.length == 0, showText: this.props.viewType === 'ToolPanel' }, this.props.viewType === 'ToolPanel' && 'Clear'),
37
37
  React.createElement(SimpleButton_1.default, { "aria-label": isAtLeastOneFilterActive ? 'Suspend All Filters' : 'Resume All Filters', className: (0, join_1.default)(`ab-${elementType}__Filter__suspend-button`, isAtLeastOneFilterActive && `ab-${elementType}__Filter__suspend-all`, !isAtLeastOneFilterActive && `ab-${elementType}__Filter__un-suspend-all`), disabled: !isAtLeastOneFilter, onClick: handleSuspendUnsuspendAll, tone: isAtLeastOneFilterActive ? 'neutral' : 'success', variant: "text", icon: isAtLeastOneFilterActive ? 'pause' : 'play', accessLevel: this.props.accessLevel })),
38
- React.createElement(rebass_1.Flex, { alignItems: "center" }, this.props.api.filterApi.columnFilterApi.isQuickFilterAvailable() && (React.createElement(CheckBox_1.CheckBox, { className: `ab-${elementType}__Filter__active-check`, disabled: this.props.accessLevel === 'ReadOnly' ||
38
+ React.createElement(rebass_1.Flex, { alignItems: "center" }, this.props.api.filterApi.columnFilterApi.isQuickFilterAvailable() && (React.createElement(CheckBox_1.CheckBox, { "data-name": "quick-filter-toggle", className: `ab-${elementType}__Filter__active-check`, disabled: this.props.accessLevel === 'ReadOnly' ||
39
39
  this.props.api.layoutApi.isCurrentLayoutPivot(), marginTop: 0, marginBottom: 0, fontSize: 2, padding: 1, checked: this.props.IsQuickFilterVisible, onChange: (checked) => {
40
40
  checked ? this.props.onShowQuickFilterBar() : this.props.onHideQuickFilterBar();
41
41
  } }, "Filter Bar")))));
@@ -266,7 +266,8 @@ const ColumnsSection = (props) => {
266
266
  });
267
267
  }
268
268
  }
269
- if (adaptable.api.gridApi.isTreeDataGrid()) {
269
+ if (adaptable.api.gridApi.isTreeDataGrid() &&
270
+ !allColumns.find((col) => col.columnId === GeneralConstants_1.AG_GRID_GROUPED_COLUMN)) {
270
271
  allColumns.unshift((0, ColumnApiImpl_1.generateAutoTreeSingleColumn)());
271
272
  }
272
273
  const colIdToCol = allColumns.reduce((acc, col) => {
@@ -200,7 +200,9 @@ export declare class AdaptableAgGrid implements IAdaptable {
200
200
  getDisplayValueFromRawValue(rowNode: IRowNode, columnId: string, rawValue: any): string | undefined;
201
201
  private getCleanValue;
202
202
  getNormalisedValueFromRawValue(rawValue: any, column: AdaptableColumn): string | number | boolean | Date | unknown;
203
+ private __updateColumnModelAndRefreshGrid_already_called;
203
204
  updateColumnModelAndRefreshGrid(): void;
205
+ _updateColumnModelAndRefreshGridNow(): void;
204
206
  redrawBody(): void;
205
207
  refreshHeader(): void;
206
208
  redrawRows(rowNodes?: IRowNode[]): void;
@@ -183,6 +183,7 @@ class AdaptableAgGrid {
183
183
  }
184
184
  return this.emitter.onIncludeFired(eventName, callback);
185
185
  };
186
+ this.__updateColumnModelAndRefreshGrid_already_called = false;
186
187
  this.lifecycleState = 'initial';
187
188
  this.emitter = new Emitter_1.default();
188
189
  this.agGridOptionsService = new AgGridOptionsService_1.AgGridOptionsService(this);
@@ -716,18 +717,30 @@ You need to define at least one Layout!`);
716
717
  };
717
718
  }
718
719
  return (params) => {
720
+ // might be a summary row
721
+ if (params.data?.[RowSummary_1.ROW_SUMMARY_ROW_ID]) {
722
+ return params.data[RowSummary_1.ROW_SUMMARY_ROW_ID];
723
+ }
724
+ if (params.level > 0) {
725
+ const parentKeys = params.parentKeys ?? [];
726
+ const values = Object.values(params.data);
727
+ let hash = 0;
728
+ for (let i = 0; i < values.length; i++) {
729
+ const str = String(values[i] ?? '');
730
+ for (let j = 0; j < str.length; j++) {
731
+ hash = ((hash << 5) - hash + str.charCodeAt(j)) | 0;
732
+ }
733
+ }
734
+ const id = [...parentKeys, Math.abs(hash)].join('/');
735
+ return id;
736
+ }
719
737
  if (params.data?.[primaryKey]) {
720
738
  const primaryKeyValue = params.data[primaryKey];
721
739
  return typeof primaryKeyValue === 'number'
722
740
  ? `${primaryKeyValue}`
723
741
  : params.data[primaryKey];
724
742
  }
725
- // might be a summary row
726
- if (params.data?.[RowSummary_1.ROW_SUMMARY_ROW_ID]) {
727
- return params.data[RowSummary_1.ROW_SUMMARY_ROW_ID];
728
- }
729
- // AFL 2024.08.17 - no idea why is this here and when it's used
730
- // might be a group row
743
+ // fallback
731
744
  const parentKeys = params.parentKeys ?? [];
732
745
  const values = Object.values(params.data);
733
746
  if (values.length) {
@@ -1076,6 +1089,20 @@ You need to define at least one Layout!`);
1076
1089
  color: '#aaaaaa',
1077
1090
  pattern: 'Solid',
1078
1091
  },
1092
+ },
1093
+ // see #EXCEL_EXPORT_DATA_TYPES
1094
+ {
1095
+ id: 'stringExcelType',
1096
+ dataType: 'String',
1097
+ }, {
1098
+ id: 'booleanExcelType',
1099
+ dataType: 'Boolean',
1100
+ }, {
1101
+ id: 'dateExcelType',
1102
+ dataType: 'DateTime',
1103
+ }, {
1104
+ id: 'numberExcelType',
1105
+ dataType: 'Number',
1079
1106
  });
1080
1107
  this.agGridExportAdapter.originalExcelStyles = excelStyles;
1081
1108
  this.agGridExportAdapter.DANGER_excelStyles = this.agGridExportAdapter.originalExcelStyles;
@@ -1869,6 +1896,20 @@ You need to define at least one Layout!`);
1869
1896
  return rawValue;
1870
1897
  }
1871
1898
  updateColumnModelAndRefreshGrid() {
1899
+ if (this.__updateColumnModelAndRefreshGrid_already_called) {
1900
+ return;
1901
+ }
1902
+ try {
1903
+ this._updateColumnModelAndRefreshGridNow();
1904
+ this.__updateColumnModelAndRefreshGrid_already_called = true;
1905
+ }
1906
+ finally {
1907
+ queueMicrotask(() => {
1908
+ this.__updateColumnModelAndRefreshGrid_already_called = false;
1909
+ });
1910
+ }
1911
+ }
1912
+ _updateColumnModelAndRefreshGridNow() {
1872
1913
  this.logger.info(`Updating Column Model and Refreshing Grid.`);
1873
1914
  this.deriveAdaptableColumnStateFromAgGrid();
1874
1915
  this.agGridColumnAdapter.setupColumns();
@@ -3172,11 +3213,6 @@ You need to define at least one Layout!`);
3172
3213
  return this.agGridModulesAdapter.isAgGridModuleRegistered('CsvExportModule');
3173
3214
  }
3174
3215
  isQuickFilterAvailable() {
3175
- if (this.api.layoutApi.isCurrentLayoutPivot() &&
3176
- this.adaptableOptions.filterOptions.useAdaptableFiltering) {
3177
- // hide completely the quick filter if pivot is enabled
3178
- return false;
3179
- }
3180
3216
  return this.hasFloatingFilterOnAtLeastOneColumn(this.agGridAdapter.getAgGridApi().getColumnDefs());
3181
3217
  }
3182
3218
  hasFloatingFilterOnAtLeastOneColumn(columnDefs) {
@@ -3555,8 +3591,8 @@ You need to define at least one Layout!`);
3555
3591
  isRowGroupDifferentInLayout(one, other) {
3556
3592
  const prevRowGroupedColumns = one.RowGroupedColumns || one.PivotGroupedColumns || [];
3557
3593
  const currentRowGroupedColumns = other.RowGroupedColumns || other.PivotGroupedColumns || [];
3558
- const prevRowGroupDisplayType = one.RowGroupDisplayType;
3559
- const currentRowGroupDisplayType = other.RowGroupDisplayType;
3594
+ const prevRowGroupDisplayType = one.RowGroupDisplayType ?? 'single';
3595
+ const currentRowGroupDisplayType = other.RowGroupDisplayType ?? 'single';
3560
3596
  if (prevRowGroupDisplayType !== currentRowGroupDisplayType) {
3561
3597
  return true;
3562
3598
  }
@@ -174,11 +174,27 @@ class AgGridColumnAdapter {
174
174
  if (!gridCell.column) {
175
175
  return null;
176
176
  }
177
- // if a VisualExcel report format export is in progress, we are interested only in the Excel Style Class
178
- if (this.adaptableApi.exportApi.internalApi.isVisualDataExportInProgress()) {
177
+ const isExcelExport = this.adaptableApi.exportApi.internalApi.isExcelExportInProgress();
178
+ const isVisualDataExport = this.adaptableApi.exportApi.internalApi.isVisualDataExportInProgress();
179
+ if (isExcelExport || isVisualDataExport) {
180
+ const excelStyleClasses = [];
179
181
  const userDefinedCellClass = typeof userCellClass === 'function' ? userCellClass(params) : userCellClass;
180
- const cellClassKey = AgGridExportAdapter_1.AgGridExportAdapter.getExcelClassNameForCell(colId, gridCell.primaryKeyValue, userDefinedCellClass);
181
- return this.adaptableInstance.agGridExportAdapter.getExcelStyleIdForCellClassKey(cellClassKey);
182
+ if (userDefinedCellClass) {
183
+ if (Array.isArray(userDefinedCellClass)) {
184
+ excelStyleClasses.push(...userDefinedCellClass.filter(Boolean));
185
+ }
186
+ else {
187
+ excelStyleClasses.push(userDefinedCellClass);
188
+ }
189
+ }
190
+ if (isVisualDataExport) {
191
+ const cellClassKey = AgGridExportAdapter_1.AgGridExportAdapter.getExcelClassNameForCell(colId, gridCell.primaryKeyValue, userDefinedCellClass);
192
+ const customCellClass = this.adaptableInstance.agGridExportAdapter.getExcelStyleIdForCellClassKey(cellClassKey);
193
+ if (customCellClass) {
194
+ excelStyleClasses.push(customCellClass);
195
+ }
196
+ }
197
+ return excelStyleClasses.length ? excelStyleClasses : null;
182
198
  }
183
199
  const isQuickSearchActive = this.isQuickSearchActive(gridCell);
184
200
  const editableClassName = this.getEditableCellClass(gridCell, params);
@@ -617,7 +633,7 @@ class AgGridColumnAdapter {
617
633
  const isFloatingFilterDisabled = !colDef.filter ||
618
634
  !colDef.floatingFilter ||
619
635
  !this.adaptableOptions.filterOptions.useAdaptableFiltering ||
620
- !this.adaptableOptions.filterOptions.columnFilterOptions.showQuickFilter;
636
+ !this.adaptableApi.filterApi.columnFilterApi.isQuickFilterVisible();
621
637
  if (this.adaptableApi.columnApi.isAutoRowGroupColumn(col.getColId())) {
622
638
  this.setColDefProperty(col, 'floatingFilter', (original_floatingFilter) => {
623
639
  // the floating filter for the group column is "inherited" from the base column
@@ -808,10 +824,47 @@ class AgGridColumnAdapter {
808
824
  }
809
825
  setupColumnComparator({ col, colId, abColumn }) {
810
826
  const customSort = this.adaptableApi.customSortApi.getCustomSortForColumn(colId);
811
- const columnSortComparer = this.adaptableApi.customSortApi.internalApi.getCustomSortComparer(abColumn.columnId);
827
+ const customSortComparer = this.adaptableApi.customSortApi.internalApi.getCustomSortComparer(abColumn.columnId);
828
+ const memoizedDateValues = new Map();
829
+ const getDateValue = (rawDateValue) => {
830
+ if (memoizedDateValues.has(rawDateValue)) {
831
+ return memoizedDateValues.get(rawDateValue);
832
+ }
833
+ const dateValue = this.adaptableApi.internalApi.parseDateValue(rawDateValue);
834
+ memoizedDateValues.set(rawDateValue, dateValue);
835
+ return dateValue;
836
+ };
812
837
  const comparatorGetter = (propName) => {
813
- return () => {
814
- return this.adaptableApi.columnApi.internalApi.getActiveColumnComparator(colId, customSort, columnSortComparer);
838
+ return (userPropertyValue) => {
839
+ // CustomSort Comparer function takes precedence over CustomSort SortedValues
840
+ if (customSortComparer) {
841
+ return customSortComparer.comparer;
842
+ }
843
+ if (customSort && !customSort.IsSuspended) {
844
+ return this.adaptableApi.customSortApi.internalApi.getDefaultCustomSortComparer(customSort.ColumnId, customSort.SortedValues);
845
+ }
846
+ if (userPropertyValue) {
847
+ return userPropertyValue;
848
+ }
849
+ // for DATE columns we have to use the normalised values (Date objects) to compare
850
+ if (abColumn.dataType === 'date') {
851
+ return (valueA, valueB) => {
852
+ const dateA = getDateValue(valueA);
853
+ const dateB = getDateValue(valueB);
854
+ if (dateA && dateB) {
855
+ return dateA.getTime() - dateB.getTime();
856
+ }
857
+ else if (dateA) {
858
+ return 1; // consider non-null dates as greater than null/undefined
859
+ }
860
+ else if (dateB) {
861
+ return -1; // consider non-null dates as greater than null/undefined
862
+ }
863
+ else {
864
+ return 0; // both are null/undefined, considered equal
865
+ }
866
+ };
867
+ }
815
868
  };
816
869
  };
817
870
  this.setColDefProperty(col, 'comparator', comparatorGetter('comparator'));
@@ -606,6 +606,23 @@ class AgGridExportAdapter {
606
606
  this.registerExcelStyle(finalCellExcelStyle, cellClassId);
607
607
  });
608
608
  }, forAllVisibleRowNodesDoConfig);
609
+ // see #EXCEL_EXPORT_DATA_TYPES
610
+ this.excelStylesCache['stringExcelType'] = {
611
+ id: 'stringExcelType',
612
+ dataType: 'String',
613
+ };
614
+ this.excelStylesCache['booleanExcelType'] = {
615
+ id: 'booleanExcelType',
616
+ dataType: 'Boolean',
617
+ };
618
+ this.excelStylesCache['dateExcelType'] = {
619
+ id: 'dateExcelType',
620
+ dataType: 'DateTime',
621
+ };
622
+ this.excelStylesCache['numberExcelType'] = {
623
+ id: 'numberExcelType',
624
+ dataType: 'Number',
625
+ };
609
626
  return Object.values(this.excelStylesCache);
610
627
  }
611
628
  registerExcelStyle(excelStyle, cellClassKey) {
@@ -19,7 +19,20 @@ class AgGridModulesAdapter {
19
19
  return this.adaptableInstance.agGridAdapter.getAgGridApi();
20
20
  }
21
21
  isAgGridModuleRegistered(moduleName) {
22
- return this.agGridApi.isModuleRegistered(moduleName);
22
+ let isModuleRegistered = this.agGridApi.isModuleRegistered(moduleName);
23
+ if (!isModuleRegistered) {
24
+ // SSRM module comes with its own implementations of Pivot, MasterDetail and TreeData
25
+ // #ssrm_pivot_module
26
+ const serverSideDependencies = [
27
+ 'PivotModule',
28
+ 'MasterDetailModule',
29
+ 'TreeDataModule',
30
+ ];
31
+ if (serverSideDependencies.includes(moduleName)) {
32
+ isModuleRegistered = this.agGridApi.isModuleRegistered('ServerSideRowModelModule');
33
+ }
34
+ }
35
+ return isModuleRegistered;
23
36
  }
24
37
  getAgGridRegisteredModules() {
25
38
  const registeredModules = [];
@@ -283,10 +283,10 @@ const Select = function (props) {
283
283
  // ignore the event if the focus is still inside the menu
284
284
  return;
285
285
  }
286
- setTimeout(() => {
286
+ requestAnimationFrame(() => {
287
287
  // wee need to wait for the single value selection to complete before closing
288
288
  closeSelectMenu();
289
- }, 100);
289
+ });
290
290
  },
291
291
  onMouseDown: (event) => {
292
292
  if (!props.isMulti) {
package/src/env.js CHANGED
@@ -2,6 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.default = {
4
4
  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" || '',
5
- PUBLISH_TIMESTAMP: 1759139207267 || Date.now(),
6
- VERSION: "21.0.5" || '--current-version--',
5
+ PUBLISH_TIMESTAMP: 1760446071135 || Date.now(),
6
+ VERSION: "21.0.7" || '--current-version--',
7
7
  };
@@ -345,9 +345,15 @@ class LayoutManager extends LMEmitter_1.LMEmitter {
345
345
  let ColumnSizing = layout.ColumnSizing || {};
346
346
  //let's also include the column widths of the pivotResult columns
347
347
  pivotResultColumns.forEach((col) => {
348
- ColumnSizing[col.getColId()] = {
349
- Width: col.getActualWidth(),
350
- };
348
+ const colId = col.getColId();
349
+ const Width = col.getActualWidth();
350
+ const initialWidth = this.initialColumnWidths[colId] ?? DEFAULT_COLUMN_WIDTH;
351
+ // but if the width is the initial/default width, don't include it in the ColumnSizing
352
+ if (Width !== initialWidth) {
353
+ ColumnSizing[colId] = {
354
+ Width,
355
+ };
356
+ }
351
357
  });
352
358
  if (!Object.keys(ColumnSizing).length) {
353
359
  ColumnSizing = undefined;
@@ -1710,7 +1716,11 @@ class LayoutManager extends LMEmitter_1.LMEmitter {
1710
1716
  }
1711
1717
  }
1712
1718
  isInPivotMode() {
1713
- return this.gridApi.isModuleRegistered('PivotModule') && this.gridApi.isPivotMode();
1719
+ // SSRM comes with its own pivot module implementation
1720
+ // see #ssrm_pivot_module
1721
+ const isModuleRegistered = this.gridApi.isModuleRegistered('PivotModule') ||
1722
+ this.gridApi.isModuleRegistered('ServerSideRowModelModule');
1723
+ return isModuleRegistered && this.gridApi.isPivotMode();
1714
1724
  }
1715
1725
  }
1716
1726
  exports.LayoutManager = LayoutManager;