@adaptabletools/adaptable-cjs 20.1.9 → 20.2.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 (66) hide show
  1. package/base.css +27 -0
  2. package/base.css.map +1 -1
  3. package/index.css +22 -0
  4. package/index.css.map +1 -1
  5. package/package.json +2 -2
  6. package/src/AdaptableInterfaces/IAdaptable.d.ts +1 -0
  7. package/src/AdaptableOptions/DefaultAdaptableOptions.js +2 -1
  8. package/src/AdaptableOptions/ExportOptions.d.ts +91 -8
  9. package/src/AdaptableOptions/FilterOptions.d.ts +4 -0
  10. package/src/AdaptableOptions/QuickSearchOptions.d.ts +2 -4
  11. package/src/AdaptableState/FormatColumnState.d.ts +8 -0
  12. package/src/AdaptableState/LayoutState.d.ts +15 -2
  13. package/src/AdaptableState/QuickSearchState.d.ts +8 -0
  14. package/src/AdaptableState/Selection/GridCell.d.ts +1 -0
  15. package/src/Api/ColumnApi.d.ts +5 -0
  16. package/src/Api/ExportApi.d.ts +23 -7
  17. package/src/Api/Implementation/ColumnApiImpl.d.ts +2 -2
  18. package/src/Api/Implementation/ColumnApiImpl.js +15 -31
  19. package/src/Api/Implementation/ExportApiImpl.d.ts +11 -4
  20. package/src/Api/Implementation/ExportApiImpl.js +50 -8
  21. package/src/Api/Implementation/LayoutHelpers.js +44 -0
  22. package/src/Api/Implementation/QuickSearchApiImpl.d.ts +4 -0
  23. package/src/Api/Implementation/QuickSearchApiImpl.js +12 -0
  24. package/src/Api/Internal/AlertInternalApi.js +1 -1
  25. package/src/Api/Internal/ExportInternalApi.d.ts +3 -8
  26. package/src/Api/Internal/ExportInternalApi.js +1 -74
  27. package/src/Api/Internal/ExpressionInternalApi.d.ts +1 -1
  28. package/src/Api/Internal/ExpressionInternalApi.js +1 -32
  29. package/src/Api/Internal/FormatColumnInternalApi.d.ts +2 -1
  30. package/src/Api/Internal/FormatColumnInternalApi.js +62 -0
  31. package/src/Api/QuickSearchApi.d.ts +16 -0
  32. package/src/Redux/Store/AdaptableStore.js +3 -2
  33. package/src/Utilities/Constants/GeneralConstants.js +2 -1
  34. package/src/View/Components/Forms/AdaptableFormControlTextClear.d.ts +1 -0
  35. package/src/View/Components/Forms/AdaptableFormControlTextClear.js +1 -0
  36. package/src/View/Components/NewScopeComponent.js +4 -4
  37. package/src/View/Dashboard/Dashboard.js +2 -4
  38. package/src/View/Layout/Wizard/sections/AggregationsSection.js +2 -2
  39. package/src/View/Layout/Wizard/sections/PivotAggregationsSection.js +2 -2
  40. package/src/View/Layout/Wizard/sections/PivotRowGroupingSection.js +6 -1
  41. package/src/View/Layout/Wizard/sections/RowGroupingSection.d.ts +4 -0
  42. package/src/View/Layout/Wizard/sections/RowGroupingSection.js +24 -20
  43. package/src/View/QuickSearch/QuickSearchInput.js +6 -1
  44. package/src/View/QuickSearch/QuickSearchPopup.js +2 -3
  45. package/src/agGrid/AdaptableAgGrid.d.ts +2 -0
  46. package/src/agGrid/AdaptableAgGrid.js +132 -38
  47. package/src/agGrid/AgGridAdapter.d.ts +4 -1
  48. package/src/agGrid/AgGridAdapter.js +89 -12
  49. package/src/agGrid/AgGridColumnAdapter.d.ts +4 -0
  50. package/src/agGrid/AgGridColumnAdapter.js +142 -35
  51. package/src/agGrid/AgGridExportAdapter.d.ts +6 -1
  52. package/src/agGrid/AgGridExportAdapter.js +103 -14
  53. package/src/agGrid/FloatingFilterWrapper.js +30 -4
  54. package/src/env.js +2 -2
  55. package/src/layout-manager/src/LayoutManagerModel.d.ts +16 -2
  56. package/src/layout-manager/src/index.d.ts +1 -1
  57. package/src/layout-manager/src/index.js +133 -18
  58. package/src/layout-manager/src/normalizeLayoutModel.d.ts +2 -4
  59. package/src/layout-manager/src/normalizeLayoutModel.js +13 -18
  60. package/src/layout-manager/src/simplifyLayoutModel.js +14 -2
  61. package/src/metamodel/adaptable.metamodel.d.ts +71 -0
  62. package/src/metamodel/adaptable.metamodel.js +1 -1
  63. package/src/types.d.ts +1 -1
  64. package/tsconfig.cjs.tsbuildinfo +1 -1
  65. package/src/Utilities/buildSortedColumnStateForLayout.d.ts +0 -7
  66. package/src/Utilities/buildSortedColumnStateForLayout.js +0 -135
@@ -139,6 +139,7 @@ class AgGridColumnAdapter {
139
139
  this.setupColumnEditable(colSetupInfo);
140
140
  this.setupColumnValueSetter(colSetupInfo);
141
141
  this.setupColumnComparator(colSetupInfo);
142
+ this.setupColumnGetFindText(colSetupInfo);
142
143
  this.setupColumnCellEditor(colSetupInfo);
143
144
  this.setupColumnHeader(colSetupInfo);
144
145
  this.setupColumnQuickFilterText(colSetupInfo);
@@ -157,6 +158,8 @@ class AgGridColumnAdapter {
157
158
  this.setColDefProperty(col, 'cellClass', (userCellClass) => {
158
159
  const formatColumns = this.adaptableApi.formatColumnApi.internalApi.getFormatColumnWithStyleClassNameForColumn(abColumn);
159
160
  const quickSearchStyleClassName = this.adaptableApi.quickSearchApi.getQuickSearchStyle().ClassName;
161
+ const quickSearchTextMatchStyle = this.getQuickSearchTextMatchStyle();
162
+ const quickSearchCurrentTextMatchStyle = this.getQuickSearchCurrentTextMatchStyle();
160
163
  const hasQuickSearchStyleClassName = StringExtensions_1.default.IsNotNullOrEmpty(quickSearchStyleClassName);
161
164
  const cellClass = (params) => {
162
165
  const gridCell = this.adaptableApi.gridApi.getGridCellFromRowNode(params.node, abColumn.columnId);
@@ -169,7 +172,7 @@ class AgGridColumnAdapter {
169
172
  const cellClassKey = AgGridExportAdapter_1.AgGridExportAdapter.getExcelClassNameForCell(colId, gridCell.primaryKeyValue, userDefinedCellClass);
170
173
  return this.adaptableInstance.agGridExportAdapter.getExcelStyleIdForCellClassKey(cellClassKey);
171
174
  }
172
- const isQuickSearchActive = hasQuickSearchStyleClassName && this.isQuickSearchActive(gridCell, params);
175
+ const isQuickSearchActive = this.isQuickSearchActive(gridCell);
173
176
  const editableClassName = this.getEditableCellClass(gridCell, params);
174
177
  const readonlyClassName = this.getReadonlyCellClass(gridCell, params);
175
178
  const editedClassName = this.getEditedCellClass(gridCell, params);
@@ -184,7 +187,10 @@ class AgGridColumnAdapter {
184
187
  !hasStyledColumn && formatColumns.length
185
188
  ? this.getFormatColumnCellClass(formatColumns, abColumn, params)
186
189
  : null,
187
- isQuickSearchActive ? quickSearchStyleClassName : null,
190
+ isQuickSearchActive && hasQuickSearchStyleClassName ? quickSearchStyleClassName : null,
191
+ isQuickSearchActive && (quickSearchTextMatchStyle || quickSearchCurrentTextMatchStyle)
192
+ ? 'ab-QuickSearchFind'
193
+ : null,
188
194
  editableClassName,
189
195
  readonlyClassName,
190
196
  editedClassName,
@@ -202,19 +208,39 @@ class AgGridColumnAdapter {
202
208
  return cellClass;
203
209
  });
204
210
  }
205
- setupColumnCellStyle({ col, colId, abColumn }) {
211
+ setupColumnCellStyle({ col }) {
206
212
  this.setColDefProperty(col, 'cellStyle', (userCellStyle) => {
207
213
  const quickSearchStyle = this.getQuickSearchCellStyle();
208
- const hasQuickSearchStyle = quickSearchStyle != undefined;
214
+ const quickSearchTextMatchStyle = this.getQuickSearchTextMatchStyle();
215
+ const quickSearchCurrentTextMatchStyle = this.getQuickSearchCurrentTextMatchStyle();
216
+ const textMatchStyle = quickSearchTextMatchStyle
217
+ ? Object.entries(quickSearchTextMatchStyle).reduce((acc, [key, value]) => {
218
+ // @ts-ignore
219
+ acc[`--ab-dynamic-${key}`] = value;
220
+ return acc;
221
+ }, {})
222
+ : undefined;
223
+ const currentTextMatchStyle = quickSearchCurrentTextMatchStyle
224
+ ? Object.entries(quickSearchCurrentTextMatchStyle).reduce((acc, [key, value]) => {
225
+ // @ts-ignore
226
+ acc[`--ab-dynamic-${key}`] = value;
227
+ return acc;
228
+ }, {})
229
+ : undefined;
230
+ const hasQuickSearchStyle = quickSearchStyle != undefined || quickSearchCurrentTextMatchStyle != undefined;
209
231
  const cellStyle = (params) => {
210
232
  const columnId = params.column.getColId();
211
233
  const gridCell = this.adaptableApi.gridApi.getGridCellFromRowNode(params.node, columnId);
212
234
  if (!gridCell || !gridCell.column) {
213
235
  return {};
214
236
  }
215
- const isQuickSearchActive = hasQuickSearchStyle && this.isQuickSearchActive(gridCell, params);
237
+ const isQuickSearchActive = hasQuickSearchStyle && this.isQuickSearchActive(gridCell);
238
+ const isCurrentMatch = this.adaptableApi.agGridApi.findGetActiveMatch()?.node === params.node;
239
+ const textStyleToApply = isCurrentMatch
240
+ ? { ...textMatchStyle, ...currentTextMatchStyle }
241
+ : textMatchStyle;
216
242
  let baseStyles = {};
217
- // this is required because otherwise, when AG Grid filters, it refershed the pivotResultColDef and the base styles get lost
243
+ // this is required because otherwise, when AG Grid filters, it refreshed the pivotResultColDef and the base styles get lost
218
244
  // if pivot result col: inherit styles from base column
219
245
  if (this.adaptableApi.columnApi.isPivotResultColumn(columnId)) {
220
246
  const baseColumn = params.column.getColDef()?.pivotValueColumn;
@@ -238,6 +264,7 @@ class AgGridColumnAdapter {
238
264
  ...this.getEditedCellStyle(gridCell, params),
239
265
  ...this.getFormatColumnAndStyledColumnCellStyle(gridCell, params),
240
266
  ...(isQuickSearchActive ? quickSearchStyle : {}),
267
+ ...(isQuickSearchActive && textStyleToApply ? textStyleToApply : {}),
241
268
  ...this.getAlertCellStyle(gridCell, params),
242
269
  ...this.getFlashingCellStyle(gridCell, params),
243
270
  ...this.getCellHighlightStyle(gridCell, params),
@@ -403,18 +430,45 @@ class AgGridColumnAdapter {
403
430
  });
404
431
  }
405
432
  setupColumnFilter({ col, colDef }) {
433
+ if (!this.adaptableOptions.filterOptions.useAdaptableFiltering) {
434
+ return;
435
+ }
436
+ // setup Auto Group Column Filter
437
+ if (this.adaptableApi.columnApi.isAutoRowGroupColumn(col.getColId())) {
438
+ if (this.adaptableApi.gridApi.isTreeDataGrid()) {
439
+ this.setColDefProperty(col, 'filter', (original_filter) => {
440
+ const autoGroupColumnDef = this.agGridApi.getGridOption('autoGroupColumnDef');
441
+ if (autoGroupColumnDef.filter != undefined) {
442
+ // we plan to provide a TreeListColumnFilter
443
+ // until then, it's the user's responsibility to explicitly set the filter in the provided `autoGroupColumnDef`
444
+ return original_filter;
445
+ }
446
+ else {
447
+ // if no filter is explicitly set, we do NOT provide a filter
448
+ return false;
449
+ }
450
+ });
451
+ }
452
+ else {
453
+ this.setColDefProperty(col, 'filter', () => {
454
+ return 'agGroupColumnFilter';
455
+ });
456
+ }
457
+ return;
458
+ }
459
+ // setup "normal" column filter
406
460
  this.setColDefProperty(col, 'filter', () => {
407
461
  if (!colDef.filter) {
408
462
  return;
409
463
  }
410
- if (!this.adaptableOptions.filterOptions.useAdaptableFiltering) {
411
- return;
412
- }
413
464
  this.agGridApi.destroyFilter(col);
414
465
  return (0, FilterWrapper_1.FilterWrapperFactory)(this.adaptableInstance);
415
466
  });
416
467
  }
417
468
  setupColumnFloatingFilterTemporarily(initialGridOptions) {
469
+ if (!this.adaptableOptions.filterOptions.useAdaptableFiltering) {
470
+ return;
471
+ }
418
472
  initialGridOptions.columnDefs
419
473
  ?.filter((colDef) => !this.isColGroupDef(colDef))
420
474
  .map((colDef) => {
@@ -428,6 +482,21 @@ class AgGridColumnAdapter {
428
482
  const isFloatingFilterDisabled = !colDef.floatingFilter ||
429
483
  !this.adaptableOptions.filterOptions.useAdaptableFiltering ||
430
484
  !this.adaptableOptions.filterOptions.columnFilterOptions.showQuickFilter;
485
+ if (this.adaptableApi.columnApi.isAutoRowGroupColumn(col.getColId())) {
486
+ this.setColDefProperty(col, 'floatingFilter', (original_floatingFilter) => {
487
+ // the floating filter for the group column is "inherited" from the base column
488
+ // via the colDef.filter = 'agGroupColumnFilter'
489
+ // see #group_inherit_column_filter
490
+ // https://www.ag-grid.com/javascript-data-grid/grouping-single-group-column/#inherit-row-grouped-columns-filters
491
+ // https://www.ag-grid.com/javascript-data-grid/grouping-multiple-group-columns/#filtering
492
+ return original_floatingFilter;
493
+ });
494
+ this.setColDefProperty(col, 'suppressFloatingFilterButton', () => {
495
+ // hide button for multi column groups
496
+ return this.adaptableApi.columnApi.isAutoRowGroupColumnForMulti(col.getColId());
497
+ });
498
+ return;
499
+ }
431
500
  this.setColDefProperty(col, 'floatingFilterComponent', () => {
432
501
  if (isFloatingFilterDisabled) {
433
502
  return;
@@ -612,42 +681,66 @@ class AgGridColumnAdapter {
612
681
  this.setColDefProperty(col, 'comparator', comparatorGetter('comparator'));
613
682
  this.setColDefProperty(col, 'pivotComparator', comparatorGetter('pivotComparator'));
614
683
  }
615
- isQuickSearchActive(gridCell, params) {
616
- const quickSearchValue = this.adaptableApi.quickSearchApi.getQuickSearchValue();
617
- if (StringExtensions_1.default.IsNullOrEmpty(quickSearchValue)) {
618
- return false;
619
- }
620
- if (!gridCell.rowNode) {
684
+ setupColumnGetFindText({ col, abColumn }) {
685
+ this.setColDefProperty(col, 'getFindText', (userGetFindText) => {
686
+ return (params) => {
687
+ const gridCell = this.adaptableApi.gridApi.getGridCellFromRowNode(params.node, abColumn.columnId);
688
+ if (!this.isCellSearchable(gridCell)) {
689
+ return null;
690
+ }
691
+ const getCellSearchText = this.adaptableOptions.quickSearchOptions.getCellSearchText;
692
+ if (getCellSearchText) {
693
+ const quickSearchValue = this.adaptableApi.quickSearchApi.getQuickSearchValue();
694
+ const quickSearchContext = {
695
+ ...this.adaptableApi.internalApi.buildBaseContext(),
696
+ gridCell,
697
+ quickSearchValue,
698
+ };
699
+ return getCellSearchText(quickSearchContext);
700
+ }
701
+ return userGetFindText?.(params) ?? gridCell.displayValue;
702
+ };
703
+ });
704
+ }
705
+ isCellSearchable(gridCell) {
706
+ const isCellSearchableFn = this.adaptableOptions.quickSearchOptions.isCellSearchable;
707
+ if (!gridCell.column) {
621
708
  return false;
622
709
  }
623
- let quickSearchContext;
624
- const isCellSearchable = this.adaptableOptions.quickSearchOptions.isCellSearchable;
625
- if (isCellSearchable) {
626
- quickSearchContext = {
710
+ if (isCellSearchableFn) {
711
+ const quickSearchValue = this.adaptableApi.quickSearchApi.getQuickSearchValue();
712
+ const quickSearchContext = {
627
713
  ...this.adaptableApi.internalApi.buildBaseContext(),
628
714
  gridCell,
629
715
  quickSearchValue,
630
716
  };
631
- if (!isCellSearchable(quickSearchContext)) {
717
+ if (!isCellSearchableFn(quickSearchContext)) {
632
718
  return false;
633
719
  }
634
720
  }
635
- const runCustomQuickSearch = this.adaptableOptions.quickSearchOptions.runCustomQuickSearch;
636
- if (runCustomQuickSearch) {
637
- if (!quickSearchContext) {
638
- quickSearchContext = {
639
- ...this.adaptableApi.internalApi.buildBaseContext(),
640
- gridCell,
641
- quickSearchValue,
642
- };
643
- }
644
- return runCustomQuickSearch(quickSearchContext);
721
+ return true;
722
+ }
723
+ isQuickSearchActive(gridCell) {
724
+ const quickSearchValue = this.adaptableApi.quickSearchApi.getQuickSearchValue();
725
+ if (!quickSearchValue) {
726
+ return false;
727
+ }
728
+ if (!this.isCellSearchable(gridCell)) {
729
+ return false;
730
+ }
731
+ let column = this.agGridApi.getColumn(gridCell.column.columnId);
732
+ if (!column && this.adaptableApi.layoutApi.isCurrentLayoutPivot()) {
733
+ column = this.agGridApi
734
+ .getAllGridColumns()
735
+ .find((col) => col.getColId() === gridCell.column.columnId);
736
+ }
737
+ if (!column) {
738
+ return false;
645
739
  }
646
- const isCaseSensitive = this.adaptableOptions.quickSearchOptions.isQuickSearchCaseSensitive;
647
- const cellDisplayValue = String(gridCell.displayValue);
648
- const displayValue = isCaseSensitive ? cellDisplayValue : cellDisplayValue.toLocaleLowerCase();
649
- const searchText = isCaseSensitive ? quickSearchValue : quickSearchValue.toLocaleLowerCase();
650
- return displayValue.indexOf(searchText) !== -1;
740
+ return (this.agGridApi.findGetNumMatches({
741
+ column,
742
+ node: gridCell.rowNode,
743
+ }) > 0);
651
744
  }
652
745
  getEditableCellClass(gridCell, params) {
653
746
  const editableCellStyle = this.adaptableApi.userInterfaceApi.getEditableCellStyle();
@@ -746,6 +839,20 @@ class AgGridColumnAdapter {
746
839
  }
747
840
  return (0, StyleHelper_1.convertAdaptableStyleToCSS)(quickSearchStyle);
748
841
  }
842
+ getQuickSearchTextMatchStyle() {
843
+ const quickSearchTextMatchStyle = this.adaptableApi.quickSearchApi.getQuickSearchTextMatchStyle();
844
+ if (!quickSearchTextMatchStyle) {
845
+ return undefined;
846
+ }
847
+ return (0, StyleHelper_1.convertAdaptableStyleToCSS)(quickSearchTextMatchStyle);
848
+ }
849
+ getQuickSearchCurrentTextMatchStyle() {
850
+ const quickSearchCurrentTextMatchStyle = this.adaptableApi.quickSearchApi.getQuickSearchCurrentTextMatchStyle();
851
+ if (!quickSearchCurrentTextMatchStyle) {
852
+ return undefined;
853
+ }
854
+ return (0, StyleHelper_1.convertAdaptableStyleToCSS)(quickSearchCurrentTextMatchStyle);
855
+ }
749
856
  getReadOnlyCellStyle(gridCell, params) {
750
857
  const editableCellStyle = this.adaptableApi.userInterfaceApi.getReadOnlyCellStyle();
751
858
  if (!editableCellStyle) {
@@ -1,13 +1,14 @@
1
1
  import { AdaptableAgGrid } from './AdaptableAgGrid';
2
2
  import { Report, ReportFormatType } from '../AdaptableState/ExportState';
3
3
  import { CsvExportParams, ExcelExportParams, ExcelStyle } from 'ag-grid-enterprise';
4
- import { ExportDestinationType, ExportResultData } from '../AdaptableOptions/ExportOptions';
4
+ import { CustomExportParams, ExportDestinationType, ExportResultData } from '../AdaptableOptions/ExportOptions';
5
5
  import { Layout } from '../AdaptableState/LayoutState';
6
6
  export interface ExportConfig {
7
7
  report: Report;
8
8
  format: ReportFormatType;
9
9
  destination: ExportDestinationType;
10
10
  showProgressIndicator: boolean;
11
+ customExportParams?: (defaultExportParams: CustomExportParams) => CustomExportParams;
11
12
  }
12
13
  interface ExportProcessContext extends ExportConfig {
13
14
  exportedColumnIds: string[];
@@ -71,5 +72,9 @@ export declare class AgGridExportAdapter {
71
72
  private getCsvSeparator;
72
73
  private computeSkipColumnHeaders;
73
74
  private computeGetCustomContentBelowRow;
75
+ private getCellExportValueFromRawValue;
76
+ private getCustomExportDateFormat;
77
+ private getCellExportValueFromRawValueByType;
78
+ private getCellExportFormatType;
74
79
  }
75
80
  export {};
@@ -5,7 +5,7 @@ const tslib_1 = require("tslib");
5
5
  const ModuleConstants_1 = require("../Utilities/Constants/ModuleConstants");
6
6
  const waitForTimeout_1 = require("../Utilities/waitForTimeout");
7
7
  const StyleHelper_1 = require("../Utilities/Helpers/StyleHelper");
8
- const FormatHelper_1 = require("../Utilities/Helpers/FormatHelper");
8
+ const FormatHelper_1 = tslib_1.__importStar(require("../Utilities/Helpers/FormatHelper"));
9
9
  const tinycolor2_1 = tslib_1.__importDefault(require("tinycolor2"));
10
10
  const StringExtensions_1 = tslib_1.__importDefault(require("../Utilities/Extensions/StringExtensions"));
11
11
  const Uuid_1 = require("../AdaptableState/Uuid");
@@ -76,7 +76,7 @@ class AgGridExportAdapter {
76
76
  if (exportContext.isVisualExcelReport) {
77
77
  // FIXME AFL patch styles only for exported columns!
78
78
  // or even better, only cells
79
- this.patchExcelStyles();
79
+ this.patchExcelStyles(exportContext);
80
80
  excelStylesWerePatched = true;
81
81
  }
82
82
  // 1. easiest case, we download the file using AG Grid
@@ -132,7 +132,11 @@ class AgGridExportAdapter {
132
132
  */
133
133
  buildExportProcessData(config) {
134
134
  const exportContext = this.buildExportProcessContext(config);
135
- const exportParams = this.buildExportParams(exportContext);
135
+ let exportParams = this.buildExportParams(exportContext);
136
+ if (typeof config?.customExportParams === 'function') {
137
+ this.logger.info(`Custom export params for ${config.report.Name} in ${config.format} format`);
138
+ exportParams = config.customExportParams(exportParams);
139
+ }
136
140
  exportContext.exportedColumnIds = exportParams.columnKeys;
137
141
  return {
138
142
  exportContext,
@@ -143,7 +147,10 @@ class AgGridExportAdapter {
143
147
  const baseExportParams = this.buildBaseExportParams(exportContext);
144
148
  if (exportContext.format === 'Excel' || exportContext.format === 'VisualExcel') {
145
149
  const excelExportParams = baseExportParams;
146
- excelExportParams.sheetName = 'Sheet 1';
150
+ const sheetName = typeof this.exportOptions.excelSheetName === 'function'
151
+ ? this.exportOptions.excelSheetName(this.adaptableApi.exportApi.internalApi.buildBaseExportContext(exportContext.report.Name, exportContext.format, exportContext.destination))
152
+ : this.exportOptions.excelSheetName;
153
+ excelExportParams.sheetName = sheetName;
147
154
  return excelExportParams;
148
155
  }
149
156
  // for everything else we use the CSV export
@@ -402,7 +409,7 @@ class AgGridExportAdapter {
402
409
  return isoFormattedDate;
403
410
  }
404
411
  }
405
- return this.adaptableApi.exportApi.internalApi.getCellExportValueFromRowNode(rowNode, columnId, exportContext.isVisualExcelReport);
412
+ return this.getCellExportValueFromRawValue(rowNode, this.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, columnId), columnId, exportContext);
406
413
  }
407
414
  processRowGroupForExcelExport(rowNode, exportContext) {
408
415
  if (this.isTreeDataGrid()) {
@@ -427,10 +434,10 @@ class AgGridExportAdapter {
427
434
  rawValue = dateRawValue;
428
435
  }
429
436
  }
430
- return this.adaptableApi.exportApi.internalApi.getCellExportValueFromRawValue(rowNode, rawValue, columnId, exportContext.isVisualExcelReport);
437
+ return this.getCellExportValueFromRawValue(rowNode, rawValue, columnId, exportContext);
431
438
  }
432
- patchExcelStyles() {
433
- const exportExcelStyles = this.buildExcelStyles();
439
+ patchExcelStyles(exportContext) {
440
+ const exportExcelStyles = this.buildExcelStyles(exportContext);
434
441
  // set DANGER_excelStyles without changing the array reference
435
442
  this.DANGER_excelStyles.splice(0, this.DANGER_excelStyles.length, ...exportExcelStyles);
436
443
  }
@@ -440,7 +447,7 @@ class AgGridExportAdapter {
440
447
  this.cellClassKey2excelStyleIdMap = {};
441
448
  this.excelStylesWithFormattedDate = {};
442
449
  }
443
- buildExcelStyles() {
450
+ buildExcelStyles(exportContext) {
444
451
  // we make sure that we start with a clean slate
445
452
  // theoretically this should have happened at the end of the export process, but just in case
446
453
  this.resetExcelStyles();
@@ -492,7 +499,7 @@ class AgGridExportAdapter {
492
499
  this.logger.warn(`Export Styling: Column with id ${columnId} not found in Adaptable`);
493
500
  return;
494
501
  }
495
- const isDateCellExportedAsFormattedValue = this.isDateCellExportedAsFormattedValue(adaptableColumn);
502
+ const isDateCellExportedAsFormattedValue = this.isDateCellExportedAsFormattedValue(adaptableColumn, exportContext);
496
503
  let cellClassParams;
497
504
  const getLazyCellClassParams = () => {
498
505
  if (!cellClassParams) {
@@ -559,6 +566,12 @@ class AgGridExportAdapter {
559
566
  mostRelevantFormatColumn?.DisplayFormat?.Options?.Pattern;
560
567
  }
561
568
  if (dateFormatPattern) {
569
+ const customDateFormatPattern = typeof dateFormatPattern === 'function'
570
+ ? dateFormatPattern({
571
+ ...this.adaptableApi.exportApi.internalApi.buildBaseExportContext(exportContext.report.Name, exportContext.format, exportContext.destination),
572
+ column: adaptableColumn,
573
+ })
574
+ : dateFormatPattern;
562
575
  const normalisedValue = this._adaptableInstance.getNormalisedValueFromRawValue(rawValue, abColumn);
563
576
  if (normalisedValue) {
564
577
  // we have to pass the date in the ISO format to Excel
@@ -569,7 +582,7 @@ class AgGridExportAdapter {
569
582
  });
570
583
  if (isoFormattedValue) {
571
584
  finalCellExcelStyle.dataType = 'DateTime';
572
- finalCellExcelStyle.numberFormat = { format: dateFormatPattern };
585
+ finalCellExcelStyle.numberFormat = { format: customDateFormatPattern };
573
586
  // create a new cell key to ensure any user provided className does not interfere
574
587
  const cellKey = AgGridExportAdapter.getExcelClassNameForCell(column.getColId(), this.adaptableApi.gridApi.getPrimaryKeyValueForRowNode(node));
575
588
  // we need to register so that later the cellProcessor will put the isoFormattedValue through (thus giving the formatting responsability to Excel)
@@ -595,11 +608,10 @@ class AgGridExportAdapter {
595
608
  registerExcelStyleWithFormattedDate(cellClassId, isoFormattedValue) {
596
609
  this.excelStylesWithFormattedDate[cellClassId] = isoFormattedValue;
597
610
  }
598
- isDateCellExportedAsFormattedValue(abColumn) {
611
+ isDateCellExportedAsFormattedValue(abColumn, exportContext) {
599
612
  return (!!this.exportOptions.exportDateFormat ||
600
613
  // FIXME AFL move this method here
601
- this.adaptableApi.exportApi.internalApi.getCellExportFormatType(abColumn, 'date') ===
602
- 'formattedValue');
614
+ this.getCellExportFormatType(abColumn, 'date', exportContext) === 'formattedValue');
603
615
  }
604
616
  convertCSSToExcelStyle(style) {
605
617
  const getHexColor = (color) => {
@@ -789,5 +801,82 @@ class AgGridExportAdapter {
789
801
  return detailRows;
790
802
  };
791
803
  }
804
+ getCellExportValueFromRawValue(rowNode, cellRawValue, columnId, exportContext) {
805
+ if (StringExtensions_1.default.IsNullOrEmpty(cellRawValue)) {
806
+ return cellRawValue;
807
+ }
808
+ const column = this.adaptableApi.columnApi.getColumnWithColumnId(columnId);
809
+ const columnDataType = column.dataType;
810
+ // 1. if it is a VisualExcel report format, we always ONLY send the formatted value and ignore all other properties
811
+ if (exportContext.isVisualExcelReport) {
812
+ return this.getCellExportValueFromRawValueByType(rowNode, cellRawValue, columnId, 'formattedValue');
813
+ }
814
+ const isDateColumn = columnDataType === 'date' || columnDataType === 'dateString';
815
+ // 2. if this is a date column and there is a custom export date format provided, that will next take precedence
816
+ if (isDateColumn) {
817
+ const customExportDateFormat = this.getCustomExportDateFormat(column, exportContext);
818
+ if (!!customExportDateFormat) {
819
+ return FormatHelper_1.default.DateFormatter(cellRawValue, {
820
+ Pattern: customExportDateFormat,
821
+ });
822
+ }
823
+ }
824
+ // 3. in all other cases check the general export format types
825
+ const cellExportFormat = this.getCellExportFormatType(column, columnDataType, exportContext);
826
+ return this.getCellExportValueFromRawValueByType(rowNode, cellRawValue, columnId, cellExportFormat);
827
+ }
828
+ getCustomExportDateFormat(column, exportContext) {
829
+ const exportDateFormatOption = this.adaptableApi.optionsApi.getExportOptions().exportDateFormat;
830
+ return typeof exportDateFormatOption === 'function'
831
+ ? exportDateFormatOption({
832
+ ...this.adaptableApi.exportApi.internalApi.buildBaseExportContext(exportContext.report.Name, exportContext.format, exportContext.destination),
833
+ column,
834
+ })
835
+ : exportDateFormatOption;
836
+ }
837
+ getCellExportValueFromRawValueByType(rowNode, cellRawValue, columnId,
838
+ // default to rawValue if, for some reason, the configs provide invalid values
839
+ type = 'rawValue') {
840
+ return type === 'rawValue'
841
+ ? cellRawValue
842
+ : // type === formattedValue
843
+ this.adaptableApi.gridApi.getDisplayValueFromRawValue(rowNode, columnId, cellRawValue);
844
+ }
845
+ getCellExportFormatType(column, columnDataType, exportContext) {
846
+ const exportDataFormat = this.exportOptions.exportDataFormat;
847
+ // First check if a function was provided and return the result
848
+ if (exportDataFormat != null && typeof exportDataFormat === 'function') {
849
+ const context = {
850
+ ...this.adaptableApi.exportApi.internalApi.buildBaseExportContext(exportContext.report.Name, exportContext.format, exportContext.destination),
851
+ column: column,
852
+ };
853
+ return exportDataFormat(context);
854
+ }
855
+ // Next Check if a "hard-coded" value has been provided and return that
856
+ if (exportDataFormat === 'rawValue') {
857
+ return 'rawValue';
858
+ }
859
+ if (exportDataFormat === 'formattedValue') {
860
+ return 'formattedValue';
861
+ }
862
+ // Finally test if a DataType object has been provided and return the relevant property
863
+ const dataFormatDataType = exportDataFormat;
864
+ if (dataFormatDataType) {
865
+ // format is customized based on column data type
866
+ switch (columnDataType) {
867
+ case 'text':
868
+ return dataFormatDataType.text;
869
+ case 'number':
870
+ return dataFormatDataType.number;
871
+ case 'date':
872
+ case 'dateString':
873
+ return dataFormatDataType.date;
874
+ default:
875
+ // default to rawValue for all other column types
876
+ return 'rawValue';
877
+ }
878
+ }
879
+ return 'rawValue';
880
+ }
792
881
  }
793
882
  exports.AgGridExportAdapter = AgGridExportAdapter;
@@ -33,11 +33,37 @@ const FloatingFilterWrapperFactory = (adaptable) => {
33
33
  function getNotifyModel(colId, onModelChange) {
34
34
  return (0, getAgGridFilterNotifyModelFn_1.getAgGridFilterNotifyModelFn)(adaptableApi, colId, onModelChange);
35
35
  }
36
+ function findParentWithClass(element, className, stopClasses, applyToAll) {
37
+ let current = element.parentElement;
38
+ while (current) {
39
+ // Stop traversing if we hit any of the stop classes
40
+ if (stopClasses.some((stopClass) => current.classList.contains(stopClass))) {
41
+ return null;
42
+ }
43
+ if (current.classList.contains(className)) {
44
+ return current;
45
+ }
46
+ applyToAll?.(current);
47
+ current = current.parentElement;
48
+ }
49
+ return null;
50
+ }
36
51
  function patchParentElement(filterContainer) {
37
- if (filterContainer) {
38
- // todo: consider theme
39
- filterContainer.parentElement.style.overflow = 'visible';
40
- filterContainer.parentElement.parentElement.style.padding = 'var(--ab-space-1)';
52
+ if (!filterContainer) {
53
+ return;
54
+ }
55
+ const stopClasses = ['ag-header-row', 'ag-header-row-column-filter'];
56
+ // Find and update floating filter body
57
+ const filterBody = findParentWithClass(filterContainer, 'ag-floating-filter-full-body', stopClasses, (currentElem) => {
58
+ currentElem.style.height = '100%';
59
+ });
60
+ if (filterBody) {
61
+ filterBody.style.overflow = 'visible';
62
+ }
63
+ // Find and update header cell
64
+ const headerCell = findParentWithClass(filterContainer, 'ag-header-cell', stopClasses);
65
+ if (headerCell?.classList.contains('ag-floating-filter')) {
66
+ headerCell.style.padding = 'var(--ab-space-1)';
41
67
  }
42
68
  }
43
69
  if (adaptable.isAgGridInitialising) {
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: 1749212744534 || Date.now(),
6
- VERSION: "20.1.9" || '--current-version--',
5
+ PUBLISH_TIMESTAMP: 1749490708802 || Date.now(),
6
+ VERSION: "20.2.0-canary.1" || '--current-version--',
7
7
  };
@@ -73,6 +73,20 @@ export interface BaseLayoutModel {
73
73
  RowGroupDisplay: 'collapsed';
74
74
  Values: any[][];
75
75
  };
76
+ /**
77
+ * Behaviour for Expanding / Collapsing Column Groups
78
+ */
79
+ ColumnGroupValues?: {
80
+ ColumnGroupDisplay: 'always-expanded';
81
+ } | {
82
+ ColumnGroupDisplay: 'expanded';
83
+ Values: any[];
84
+ } | {
85
+ ColumnGroupDisplay: 'always-collapsed';
86
+ } | {
87
+ ColumnGroupDisplay: 'collapsed';
88
+ Values: any[];
89
+ };
76
90
  /**
77
91
  * Hides aggFunc name in the column header: e.g. 'sum(Bank Balance)' will just be 'Bank Balance'
78
92
  */
@@ -85,9 +99,9 @@ export interface BaseLayoutModel {
85
99
  [columnId: string]: 'left' | 'right';
86
100
  };
87
101
  /**
88
- * Display Grand Total Row at the top or bottom of the Pivot Table
102
+ * Display Grand Total Row of the Pivot Table
89
103
  */
90
- GrandTotalRow?: 'top' | 'bottom' | boolean;
104
+ GrandTotalRow?: 'top' | 'bottom' | 'pinnedTop' | 'pinnedBottom' | boolean;
91
105
  }
92
106
  export type ColumnAggregationModel = {
93
107
  aggFunc: string | true;
@@ -76,7 +76,7 @@ export declare class LayoutManager<DATA_TYPE = any> extends LMEmitter {
76
76
  autoSizeColumns(columnIds?: string[]): false | string[];
77
77
  private applyPivotLayout;
78
78
  applyPivotTotals(layout: PivotLayoutModel): void;
79
- applyPivotExpandLevel(layout: PivotLayoutModel): void;
79
+ applyColumnGroupCollapseExpandState(layout: PivotLayoutModel | TableLayoutModel): void;
80
80
  private withSuppressColumnAnimation;
81
81
  private patchColDefType;
82
82
  private setupPivotTotals;