@adaptabletools/adaptable 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 +1 -1
- package/src/AdaptableOptions/DateInputOptions.d.ts +1 -1
- package/src/Api/Implementation/LayoutHelpers.js +23 -6
- package/src/Api/Internal/AdaptableInternalApi.d.ts +1 -0
- package/src/Api/Internal/AdaptableInternalApi.js +9 -0
- package/src/Api/Internal/ColumnInternalApi.d.ts +1 -4
- package/src/Api/Internal/ColumnInternalApi.js +0 -12
- package/src/Api/Internal/ExportInternalApi.d.ts +1 -0
- package/src/Api/Internal/ExportInternalApi.js +3 -0
- package/src/Utilities/Helpers/DateHelper.d.ts +0 -1
- package/src/Utilities/Helpers/DateHelper.js +28 -16
- package/src/View/Filter/FilterViewPanel.js +1 -1
- package/src/View/Layout/Wizard/sections/ColumnsSection.js +3 -2
- package/src/agGrid/AdaptableAgGrid.d.ts +2 -0
- package/src/agGrid/AdaptableAgGrid.js +49 -13
- package/src/agGrid/AgGridColumnAdapter.js +61 -8
- package/src/agGrid/AgGridExportAdapter.js +17 -0
- package/src/agGrid/AgGridModulesAdapter.js +14 -1
- package/src/components/Select/Select.js +2 -2
- package/src/env.js +2 -2
- package/src/layout-manager/src/index.js +14 -4
- package/tsconfig.esm.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adaptabletools/adaptable",
|
|
3
|
-
"version": "21.0.
|
|
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",
|
|
@@ -28,6 +28,23 @@ export const layoutModelToLayoutState = (layoutModel) => {
|
|
|
28
28
|
function cleanupAdaptableObjectPrimitives(layout) {
|
|
29
29
|
const l = layout;
|
|
30
30
|
for (const key in l) {
|
|
31
|
+
if (key === 'ColumnFilters') {
|
|
32
|
+
// we don't want to cleanup ColumnFilters
|
|
33
|
+
// as we rely on the Uuids for identifying the filters
|
|
34
|
+
if (Array.isArray(l[key])) {
|
|
35
|
+
l[key].forEach((item) => {
|
|
36
|
+
if (typeof item === 'object') {
|
|
37
|
+
// but we do want to cleanup further down - eg: predicates in the filter
|
|
38
|
+
for (const k in item) {
|
|
39
|
+
if (typeof item[k] === 'object') {
|
|
40
|
+
removeAdaptableObjectPrimitivesInlineDeep(item[k]);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
31
48
|
if (typeof l[key] === 'object') {
|
|
32
49
|
removeAdaptableObjectPrimitivesInlineDeep(l[key]);
|
|
33
50
|
}
|
|
@@ -355,9 +372,9 @@ export const tableLayoutModelToTableLayout = (layoutModel) => {
|
|
|
355
372
|
if (layoutModel.Ignore_Metadata) {
|
|
356
373
|
tableLayout.Metadata = layoutModel.Ignore_Metadata;
|
|
357
374
|
}
|
|
358
|
-
if (layoutModel.RowGroupDisplayType) {
|
|
359
|
-
|
|
360
|
-
}
|
|
375
|
+
// if (layoutModel.RowGroupDisplayType) {
|
|
376
|
+
tableLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType ?? 'single';
|
|
377
|
+
// }
|
|
361
378
|
if (layoutModel.RowGroupedColumns) {
|
|
362
379
|
tableLayout.RowGroupedColumns = layoutModel.RowGroupedColumns;
|
|
363
380
|
}
|
|
@@ -511,9 +528,9 @@ export const pivotLayoutModelToPivotLayout = (layoutModel) => {
|
|
|
511
528
|
pivotLayout.ColumnGroupValues.ExceptionGroupKeys = layoutModel.ColumnGroupValues.Values;
|
|
512
529
|
}
|
|
513
530
|
}
|
|
514
|
-
if (layoutModel.RowGroupDisplayType) {
|
|
515
|
-
|
|
516
|
-
}
|
|
531
|
+
// if (layoutModel.RowGroupDisplayType) {
|
|
532
|
+
pivotLayout.RowGroupDisplayType = layoutModel.RowGroupDisplayType ?? 'single';
|
|
533
|
+
// }
|
|
517
534
|
return pivotLayout;
|
|
518
535
|
};
|
|
519
536
|
export const isPivotLayout = (layout) => Array.isArray(layout.PivotColumns);
|
|
@@ -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
|
}
|
|
@@ -5,6 +5,7 @@ import StringExtensions from '../../Utilities/Extensions/StringExtensions';
|
|
|
5
5
|
import { ADAPTABLE_ID } from '../../Utilities/Constants/GeneralConstants';
|
|
6
6
|
import { waitForCondition } from '../../Utilities/waitForCondition';
|
|
7
7
|
import { isAdaptableCustomIcon, isAdaptableSystemIcon } from '../../components/Icon';
|
|
8
|
+
import { parseDateValue } from '../../Utilities/Helpers/DateHelper';
|
|
8
9
|
export class AdaptableInternalApi extends ApiBase {
|
|
9
10
|
getInternalState() {
|
|
10
11
|
return this.getAdaptableState().Internal;
|
|
@@ -439,4 +440,12 @@ export class AdaptableInternalApi extends ApiBase {
|
|
|
439
440
|
setCellSummaryInfo(cellSummaryInfo) {
|
|
440
441
|
this.dispatchAction(InternalRedux.SetCellSummaryInfo(cellSummaryInfo));
|
|
441
442
|
}
|
|
443
|
+
parseDateValue(dateValue) {
|
|
444
|
+
const dateFormat = this.getUserInterfaceOptions().dateInputOptions.dateFormat;
|
|
445
|
+
if (dateFormat === 'yyyy-MM-dd') {
|
|
446
|
+
// if the format is ISO, we don't pass it so that we use the date-fns `parseISO` which is more robust
|
|
447
|
+
return parseDateValue(dateValue);
|
|
448
|
+
}
|
|
449
|
+
return parseDateValue(dateValue, dateFormat);
|
|
450
|
+
}
|
|
442
451
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { ApiBase } from '../Implementation/ApiBase';
|
|
2
|
-
import { ColDef, Column, HeaderValueGetterParams
|
|
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;
|
|
@@ -64,18 +64,6 @@ export class ColumnInternalApi extends ApiBase {
|
|
|
64
64
|
getAgGridColumnForAdaptableColumn(columnId) {
|
|
65
65
|
return this._adaptable.getAgGridColumnForColumnId(columnId);
|
|
66
66
|
}
|
|
67
|
-
getActiveColumnComparator(columnId, customSort, customSortComparer) {
|
|
68
|
-
if ((!customSort || customSort?.IsSuspended) && !customSortComparer) {
|
|
69
|
-
// defaults to AG-Grid column definition comparator if no CustomSort is defined&active
|
|
70
|
-
const colDefComparator = this._adaptable.agGridColumnAdapter.getUserColDefProperty(columnId, 'comparator');
|
|
71
|
-
return colDefComparator;
|
|
72
|
-
}
|
|
73
|
-
// CustomSort Comparer function takes precedence over CustomSort SortedValues
|
|
74
|
-
const comparerFunction = customSortComparer
|
|
75
|
-
? customSortComparer.comparer
|
|
76
|
-
: this.getCustomSortApi().internalApi.getDefaultCustomSortComparer(customSort.ColumnId, customSort.SortedValues);
|
|
77
|
-
return comparerFunction;
|
|
78
|
-
}
|
|
79
67
|
isSpecialColumn(columnId, column = null) {
|
|
80
68
|
if (column) {
|
|
81
69
|
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;
|
|
@@ -82,6 +82,9 @@ export class ExportInternalApi extends ApiBase {
|
|
|
82
82
|
isVisualDataExportInProgress() {
|
|
83
83
|
return this.getAdaptableState().Internal.Export.inProgress?.reportFormat === 'VisualExcel';
|
|
84
84
|
}
|
|
85
|
+
isExcelExportInProgress() {
|
|
86
|
+
return this.getAdaptableState().Internal.Export.inProgress?.reportFormat === 'Excel';
|
|
87
|
+
}
|
|
85
88
|
createSystemReport(systemReportName) {
|
|
86
89
|
switch (systemReportName) {
|
|
87
90
|
case 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;
|
|
@@ -23,6 +23,9 @@ export const parseToISO = (date, dateFormat) => {
|
|
|
23
23
|
const dateInstance = parseDateValue(date, dateFormat);
|
|
24
24
|
return isValidDate(dateInstance) ? dateToISO(dateInstance) : '';
|
|
25
25
|
};
|
|
26
|
+
// !!!
|
|
27
|
+
// AFL: ideally we should NEVER call directly this method, but use the AdaptableInternalApi.parseDateValue() instead
|
|
28
|
+
// we should refactor this with the first opportunity
|
|
26
29
|
export const parseDateValue = (dateValue, dateFormat) => {
|
|
27
30
|
if (dateValue == undefined || (typeof dateValue === 'string' && dateValue.trim() === '')) {
|
|
28
31
|
return undefined;
|
|
@@ -30,27 +33,36 @@ export const parseDateValue = (dateValue, dateFormat) => {
|
|
|
30
33
|
if (dateValue instanceof Date) {
|
|
31
34
|
return !isNaN(dateValue.getTime()) ? dateValue : undefined;
|
|
32
35
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
else {
|
|
38
|
-
// typeof dateValue === 'string'
|
|
39
|
-
if (dateFormat) {
|
|
40
|
-
dateInstance = parse(dateValue, dateFormat, new Date());
|
|
36
|
+
try {
|
|
37
|
+
let dateInstance;
|
|
38
|
+
if (typeof dateValue === 'number') {
|
|
39
|
+
dateInstance = new Date(dateValue);
|
|
41
40
|
}
|
|
42
41
|
else {
|
|
43
|
-
|
|
42
|
+
// typeof dateValue === 'string'
|
|
43
|
+
if (dateFormat) {
|
|
44
|
+
dateInstance = parse(dateValue, dateFormat, new Date());
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
dateInstance = parseISO(dateValue);
|
|
48
|
+
}
|
|
49
|
+
if (!isValidDate(dateInstance)) {
|
|
50
|
+
// last chance: try to use the native Date.parse(), https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse
|
|
51
|
+
dateInstance = new Date(Date.parse(dateValue));
|
|
52
|
+
}
|
|
44
53
|
}
|
|
45
54
|
if (!isValidDate(dateInstance)) {
|
|
46
|
-
|
|
47
|
-
dateInstance =
|
|
55
|
+
AdaptableLogger.consoleWarnBase(`Invalid date value "${dateValue}" - cannot be converted to a Date instance. Please make sure you specify adaptableOptions.userInterfaceOptions.dateInputOptions.dateFormat correctly.`);
|
|
56
|
+
dateInstance = undefined;
|
|
48
57
|
}
|
|
58
|
+
return dateInstance;
|
|
49
59
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
60
|
+
catch (error) {
|
|
61
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
62
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
63
|
+
AdaptableLogger.consoleErrorBase(`Error parsing date value "${dateValue}": ${errorMessage}`, {
|
|
64
|
+
stack: errorStack,
|
|
65
|
+
originalError: error,
|
|
66
|
+
});
|
|
53
67
|
}
|
|
54
|
-
return dateInstance;
|
|
55
68
|
};
|
|
56
|
-
export const parseFilterInputDate = (stringDate) => new Date(stringDate);
|
|
@@ -31,7 +31,7 @@ class FilterViewPanelComponent extends React.Component {
|
|
|
31
31
|
ArrayExtensions.IsNotNullOrEmpty(this.props.ColumnFilters) && (React.createElement(AdaptablePopover, { popupPadding: 0, className: `ab-${elementType}__Filter__info`, headerText: "", bodyText: [React.createElement(ActiveFiltersPanel, null)], useButton: true, showEvent: 'focus', hideEvent: "blur", popoverMinWidth: 400 })),
|
|
32
32
|
React.createElement(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'),
|
|
33
33
|
React.createElement(SimpleButton, { "aria-label": isAtLeastOneFilterActive ? 'Suspend All Filters' : 'Resume All Filters', className: join(`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 })),
|
|
34
|
-
React.createElement(Flex, { alignItems: "center" }, this.props.api.filterApi.columnFilterApi.isQuickFilterAvailable() && (React.createElement(CheckBox, { className: `ab-${elementType}__Filter__active-check`, disabled: this.props.accessLevel === 'ReadOnly' ||
|
|
34
|
+
React.createElement(Flex, { alignItems: "center" }, this.props.api.filterApi.columnFilterApi.isQuickFilterAvailable() && (React.createElement(CheckBox, { "data-name": "quick-filter-toggle", className: `ab-${elementType}__Filter__active-check`, disabled: this.props.accessLevel === 'ReadOnly' ||
|
|
35
35
|
this.props.api.layoutApi.isCurrentLayoutPivot(), marginTop: 0, marginBottom: 0, fontSize: 2, padding: 1, checked: this.props.IsQuickFilterVisible, onChange: (checked) => {
|
|
36
36
|
checked ? this.props.onShowQuickFilterBar() : this.props.onHideQuickFilterBar();
|
|
37
37
|
} }, "Filter Bar")))));
|
|
@@ -22,7 +22,7 @@ import { ReorderDraggable } from '../../../Components/ReorderDraggable';
|
|
|
22
22
|
import { AdaptableFormControlTextClear } from '../../../Components/Forms/AdaptableFormControlTextClear';
|
|
23
23
|
import { sortColumnIdsByOrder } from '../../../../layout-manager/src/sortColumnIdsByOrder';
|
|
24
24
|
import HelpBlock from '../../../../components/HelpBlock';
|
|
25
|
-
import { AG_GRID_SELECTION_COLUMN } from '../../../../Utilities/Constants/GeneralConstants';
|
|
25
|
+
import { AG_GRID_GROUPED_COLUMN, AG_GRID_SELECTION_COLUMN, } from '../../../../Utilities/Constants/GeneralConstants';
|
|
26
26
|
import { isPivotLayout } from '../../../../Utilities/isPivotLayout';
|
|
27
27
|
const PropertyOrderText = (props) => (React.createElement(Text, { fontWeight: 600, fontSize: 2 }, props.children));
|
|
28
28
|
const columnTypes = {
|
|
@@ -261,7 +261,8 @@ export const ColumnsSection = (props) => {
|
|
|
261
261
|
});
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
|
-
if (adaptable.api.gridApi.isTreeDataGrid()
|
|
264
|
+
if (adaptable.api.gridApi.isTreeDataGrid() &&
|
|
265
|
+
!allColumns.find((col) => col.columnId === AG_GRID_GROUPED_COLUMN)) {
|
|
265
266
|
allColumns.unshift(generateAutoTreeSingleColumn());
|
|
266
267
|
}
|
|
267
268
|
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;
|
|
@@ -179,6 +179,7 @@ export class AdaptableAgGrid {
|
|
|
179
179
|
}
|
|
180
180
|
return this.emitter.onIncludeFired(eventName, callback);
|
|
181
181
|
};
|
|
182
|
+
this.__updateColumnModelAndRefreshGrid_already_called = false;
|
|
182
183
|
this.lifecycleState = 'initial';
|
|
183
184
|
this.emitter = new Emitter();
|
|
184
185
|
this.agGridOptionsService = new AgGridOptionsService(this);
|
|
@@ -712,18 +713,30 @@ You need to define at least one Layout!`);
|
|
|
712
713
|
};
|
|
713
714
|
}
|
|
714
715
|
return (params) => {
|
|
716
|
+
// might be a summary row
|
|
717
|
+
if (params.data?.[ROW_SUMMARY_ROW_ID]) {
|
|
718
|
+
return params.data[ROW_SUMMARY_ROW_ID];
|
|
719
|
+
}
|
|
720
|
+
if (params.level > 0) {
|
|
721
|
+
const parentKeys = params.parentKeys ?? [];
|
|
722
|
+
const values = Object.values(params.data);
|
|
723
|
+
let hash = 0;
|
|
724
|
+
for (let i = 0; i < values.length; i++) {
|
|
725
|
+
const str = String(values[i] ?? '');
|
|
726
|
+
for (let j = 0; j < str.length; j++) {
|
|
727
|
+
hash = ((hash << 5) - hash + str.charCodeAt(j)) | 0;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
const id = [...parentKeys, Math.abs(hash)].join('/');
|
|
731
|
+
return id;
|
|
732
|
+
}
|
|
715
733
|
if (params.data?.[primaryKey]) {
|
|
716
734
|
const primaryKeyValue = params.data[primaryKey];
|
|
717
735
|
return typeof primaryKeyValue === 'number'
|
|
718
736
|
? `${primaryKeyValue}`
|
|
719
737
|
: params.data[primaryKey];
|
|
720
738
|
}
|
|
721
|
-
//
|
|
722
|
-
if (params.data?.[ROW_SUMMARY_ROW_ID]) {
|
|
723
|
-
return params.data[ROW_SUMMARY_ROW_ID];
|
|
724
|
-
}
|
|
725
|
-
// AFL 2024.08.17 - no idea why is this here and when it's used
|
|
726
|
-
// might be a group row
|
|
739
|
+
// fallback
|
|
727
740
|
const parentKeys = params.parentKeys ?? [];
|
|
728
741
|
const values = Object.values(params.data);
|
|
729
742
|
if (values.length) {
|
|
@@ -1072,6 +1085,20 @@ You need to define at least one Layout!`);
|
|
|
1072
1085
|
color: '#aaaaaa',
|
|
1073
1086
|
pattern: 'Solid',
|
|
1074
1087
|
},
|
|
1088
|
+
},
|
|
1089
|
+
// see #EXCEL_EXPORT_DATA_TYPES
|
|
1090
|
+
{
|
|
1091
|
+
id: 'stringExcelType',
|
|
1092
|
+
dataType: 'String',
|
|
1093
|
+
}, {
|
|
1094
|
+
id: 'booleanExcelType',
|
|
1095
|
+
dataType: 'Boolean',
|
|
1096
|
+
}, {
|
|
1097
|
+
id: 'dateExcelType',
|
|
1098
|
+
dataType: 'DateTime',
|
|
1099
|
+
}, {
|
|
1100
|
+
id: 'numberExcelType',
|
|
1101
|
+
dataType: 'Number',
|
|
1075
1102
|
});
|
|
1076
1103
|
this.agGridExportAdapter.originalExcelStyles = excelStyles;
|
|
1077
1104
|
this.agGridExportAdapter.DANGER_excelStyles = this.agGridExportAdapter.originalExcelStyles;
|
|
@@ -1865,6 +1892,20 @@ You need to define at least one Layout!`);
|
|
|
1865
1892
|
return rawValue;
|
|
1866
1893
|
}
|
|
1867
1894
|
updateColumnModelAndRefreshGrid() {
|
|
1895
|
+
if (this.__updateColumnModelAndRefreshGrid_already_called) {
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
try {
|
|
1899
|
+
this._updateColumnModelAndRefreshGridNow();
|
|
1900
|
+
this.__updateColumnModelAndRefreshGrid_already_called = true;
|
|
1901
|
+
}
|
|
1902
|
+
finally {
|
|
1903
|
+
queueMicrotask(() => {
|
|
1904
|
+
this.__updateColumnModelAndRefreshGrid_already_called = false;
|
|
1905
|
+
});
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
_updateColumnModelAndRefreshGridNow() {
|
|
1868
1909
|
this.logger.info(`Updating Column Model and Refreshing Grid.`);
|
|
1869
1910
|
this.deriveAdaptableColumnStateFromAgGrid();
|
|
1870
1911
|
this.agGridColumnAdapter.setupColumns();
|
|
@@ -3168,11 +3209,6 @@ You need to define at least one Layout!`);
|
|
|
3168
3209
|
return this.agGridModulesAdapter.isAgGridModuleRegistered('CsvExportModule');
|
|
3169
3210
|
}
|
|
3170
3211
|
isQuickFilterAvailable() {
|
|
3171
|
-
if (this.api.layoutApi.isCurrentLayoutPivot() &&
|
|
3172
|
-
this.adaptableOptions.filterOptions.useAdaptableFiltering) {
|
|
3173
|
-
// hide completely the quick filter if pivot is enabled
|
|
3174
|
-
return false;
|
|
3175
|
-
}
|
|
3176
3212
|
return this.hasFloatingFilterOnAtLeastOneColumn(this.agGridAdapter.getAgGridApi().getColumnDefs());
|
|
3177
3213
|
}
|
|
3178
3214
|
hasFloatingFilterOnAtLeastOneColumn(columnDefs) {
|
|
@@ -3551,8 +3587,8 @@ You need to define at least one Layout!`);
|
|
|
3551
3587
|
isRowGroupDifferentInLayout(one, other) {
|
|
3552
3588
|
const prevRowGroupedColumns = one.RowGroupedColumns || one.PivotGroupedColumns || [];
|
|
3553
3589
|
const currentRowGroupedColumns = other.RowGroupedColumns || other.PivotGroupedColumns || [];
|
|
3554
|
-
const prevRowGroupDisplayType = one.RowGroupDisplayType;
|
|
3555
|
-
const currentRowGroupDisplayType = other.RowGroupDisplayType;
|
|
3590
|
+
const prevRowGroupDisplayType = one.RowGroupDisplayType ?? 'single';
|
|
3591
|
+
const currentRowGroupDisplayType = other.RowGroupDisplayType ?? 'single';
|
|
3556
3592
|
if (prevRowGroupDisplayType !== currentRowGroupDisplayType) {
|
|
3557
3593
|
return true;
|
|
3558
3594
|
}
|
|
@@ -169,11 +169,27 @@ export class AgGridColumnAdapter {
|
|
|
169
169
|
if (!gridCell.column) {
|
|
170
170
|
return null;
|
|
171
171
|
}
|
|
172
|
-
|
|
173
|
-
|
|
172
|
+
const isExcelExport = this.adaptableApi.exportApi.internalApi.isExcelExportInProgress();
|
|
173
|
+
const isVisualDataExport = this.adaptableApi.exportApi.internalApi.isVisualDataExportInProgress();
|
|
174
|
+
if (isExcelExport || isVisualDataExport) {
|
|
175
|
+
const excelStyleClasses = [];
|
|
174
176
|
const userDefinedCellClass = typeof userCellClass === 'function' ? userCellClass(params) : userCellClass;
|
|
175
|
-
|
|
176
|
-
|
|
177
|
+
if (userDefinedCellClass) {
|
|
178
|
+
if (Array.isArray(userDefinedCellClass)) {
|
|
179
|
+
excelStyleClasses.push(...userDefinedCellClass.filter(Boolean));
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
excelStyleClasses.push(userDefinedCellClass);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (isVisualDataExport) {
|
|
186
|
+
const cellClassKey = AgGridExportAdapter.getExcelClassNameForCell(colId, gridCell.primaryKeyValue, userDefinedCellClass);
|
|
187
|
+
const customCellClass = this.adaptableInstance.agGridExportAdapter.getExcelStyleIdForCellClassKey(cellClassKey);
|
|
188
|
+
if (customCellClass) {
|
|
189
|
+
excelStyleClasses.push(customCellClass);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return excelStyleClasses.length ? excelStyleClasses : null;
|
|
177
193
|
}
|
|
178
194
|
const isQuickSearchActive = this.isQuickSearchActive(gridCell);
|
|
179
195
|
const editableClassName = this.getEditableCellClass(gridCell, params);
|
|
@@ -612,7 +628,7 @@ export class AgGridColumnAdapter {
|
|
|
612
628
|
const isFloatingFilterDisabled = !colDef.filter ||
|
|
613
629
|
!colDef.floatingFilter ||
|
|
614
630
|
!this.adaptableOptions.filterOptions.useAdaptableFiltering ||
|
|
615
|
-
!this.
|
|
631
|
+
!this.adaptableApi.filterApi.columnFilterApi.isQuickFilterVisible();
|
|
616
632
|
if (this.adaptableApi.columnApi.isAutoRowGroupColumn(col.getColId())) {
|
|
617
633
|
this.setColDefProperty(col, 'floatingFilter', (original_floatingFilter) => {
|
|
618
634
|
// the floating filter for the group column is "inherited" from the base column
|
|
@@ -803,10 +819,47 @@ export class AgGridColumnAdapter {
|
|
|
803
819
|
}
|
|
804
820
|
setupColumnComparator({ col, colId, abColumn }) {
|
|
805
821
|
const customSort = this.adaptableApi.customSortApi.getCustomSortForColumn(colId);
|
|
806
|
-
const
|
|
822
|
+
const customSortComparer = this.adaptableApi.customSortApi.internalApi.getCustomSortComparer(abColumn.columnId);
|
|
823
|
+
const memoizedDateValues = new Map();
|
|
824
|
+
const getDateValue = (rawDateValue) => {
|
|
825
|
+
if (memoizedDateValues.has(rawDateValue)) {
|
|
826
|
+
return memoizedDateValues.get(rawDateValue);
|
|
827
|
+
}
|
|
828
|
+
const dateValue = this.adaptableApi.internalApi.parseDateValue(rawDateValue);
|
|
829
|
+
memoizedDateValues.set(rawDateValue, dateValue);
|
|
830
|
+
return dateValue;
|
|
831
|
+
};
|
|
807
832
|
const comparatorGetter = (propName) => {
|
|
808
|
-
return () => {
|
|
809
|
-
|
|
833
|
+
return (userPropertyValue) => {
|
|
834
|
+
// CustomSort Comparer function takes precedence over CustomSort SortedValues
|
|
835
|
+
if (customSortComparer) {
|
|
836
|
+
return customSortComparer.comparer;
|
|
837
|
+
}
|
|
838
|
+
if (customSort && !customSort.IsSuspended) {
|
|
839
|
+
return this.adaptableApi.customSortApi.internalApi.getDefaultCustomSortComparer(customSort.ColumnId, customSort.SortedValues);
|
|
840
|
+
}
|
|
841
|
+
if (userPropertyValue) {
|
|
842
|
+
return userPropertyValue;
|
|
843
|
+
}
|
|
844
|
+
// for DATE columns we have to use the normalised values (Date objects) to compare
|
|
845
|
+
if (abColumn.dataType === 'date') {
|
|
846
|
+
return (valueA, valueB) => {
|
|
847
|
+
const dateA = getDateValue(valueA);
|
|
848
|
+
const dateB = getDateValue(valueB);
|
|
849
|
+
if (dateA && dateB) {
|
|
850
|
+
return dateA.getTime() - dateB.getTime();
|
|
851
|
+
}
|
|
852
|
+
else if (dateA) {
|
|
853
|
+
return 1; // consider non-null dates as greater than null/undefined
|
|
854
|
+
}
|
|
855
|
+
else if (dateB) {
|
|
856
|
+
return -1; // consider non-null dates as greater than null/undefined
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
return 0; // both are null/undefined, considered equal
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
}
|
|
810
863
|
};
|
|
811
864
|
};
|
|
812
865
|
this.setColDefProperty(col, 'comparator', comparatorGetter('comparator'));
|
|
@@ -602,6 +602,23 @@ export class AgGridExportAdapter {
|
|
|
602
602
|
this.registerExcelStyle(finalCellExcelStyle, cellClassId);
|
|
603
603
|
});
|
|
604
604
|
}, forAllVisibleRowNodesDoConfig);
|
|
605
|
+
// see #EXCEL_EXPORT_DATA_TYPES
|
|
606
|
+
this.excelStylesCache['stringExcelType'] = {
|
|
607
|
+
id: 'stringExcelType',
|
|
608
|
+
dataType: 'String',
|
|
609
|
+
};
|
|
610
|
+
this.excelStylesCache['booleanExcelType'] = {
|
|
611
|
+
id: 'booleanExcelType',
|
|
612
|
+
dataType: 'Boolean',
|
|
613
|
+
};
|
|
614
|
+
this.excelStylesCache['dateExcelType'] = {
|
|
615
|
+
id: 'dateExcelType',
|
|
616
|
+
dataType: 'DateTime',
|
|
617
|
+
};
|
|
618
|
+
this.excelStylesCache['numberExcelType'] = {
|
|
619
|
+
id: 'numberExcelType',
|
|
620
|
+
dataType: 'Number',
|
|
621
|
+
};
|
|
605
622
|
return Object.values(this.excelStylesCache);
|
|
606
623
|
}
|
|
607
624
|
registerExcelStyle(excelStyle, cellClassKey) {
|
|
@@ -16,7 +16,20 @@ export class AgGridModulesAdapter {
|
|
|
16
16
|
return this.adaptableInstance.agGridAdapter.getAgGridApi();
|
|
17
17
|
}
|
|
18
18
|
isAgGridModuleRegistered(moduleName) {
|
|
19
|
-
|
|
19
|
+
let isModuleRegistered = this.agGridApi.isModuleRegistered(moduleName);
|
|
20
|
+
if (!isModuleRegistered) {
|
|
21
|
+
// SSRM module comes with its own implementations of Pivot, MasterDetail and TreeData
|
|
22
|
+
// #ssrm_pivot_module
|
|
23
|
+
const serverSideDependencies = [
|
|
24
|
+
'PivotModule',
|
|
25
|
+
'MasterDetailModule',
|
|
26
|
+
'TreeDataModule',
|
|
27
|
+
];
|
|
28
|
+
if (serverSideDependencies.includes(moduleName)) {
|
|
29
|
+
isModuleRegistered = this.agGridApi.isModuleRegistered('ServerSideRowModelModule');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return isModuleRegistered;
|
|
20
33
|
}
|
|
21
34
|
getAgGridRegisteredModules() {
|
|
22
35
|
const registeredModules = [];
|
|
@@ -279,10 +279,10 @@ export const Select = function (props) {
|
|
|
279
279
|
// ignore the event if the focus is still inside the menu
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
|
-
|
|
282
|
+
requestAnimationFrame(() => {
|
|
283
283
|
// wee need to wait for the single value selection to complete before closing
|
|
284
284
|
closeSelectMenu();
|
|
285
|
-
}
|
|
285
|
+
});
|
|
286
286
|
},
|
|
287
287
|
onMouseDown: (event) => {
|
|
288
288
|
if (!props.isMulti) {
|
package/src/env.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
NEXT_PUBLIC_INFINITE_TABLE_LICENSE_KEY: "StartDate=2021-06-29|EndDate=2030-01-01|Owner=Adaptable|Type=distribution|TS=1624971462479|C=137829811,1004007071,2756196225,1839832928,3994409405,636616862" || '',
|
|
3
|
-
PUBLISH_TIMESTAMP:
|
|
4
|
-
VERSION: "21.0.
|
|
3
|
+
PUBLISH_TIMESTAMP: 1760446037964 || Date.now(),
|
|
4
|
+
VERSION: "21.0.7" || '--current-version--',
|
|
5
5
|
};
|
|
@@ -342,9 +342,15 @@ export class LayoutManager extends LMEmitter {
|
|
|
342
342
|
let ColumnSizing = layout.ColumnSizing || {};
|
|
343
343
|
//let's also include the column widths of the pivotResult columns
|
|
344
344
|
pivotResultColumns.forEach((col) => {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
345
|
+
const colId = col.getColId();
|
|
346
|
+
const Width = col.getActualWidth();
|
|
347
|
+
const initialWidth = this.initialColumnWidths[colId] ?? DEFAULT_COLUMN_WIDTH;
|
|
348
|
+
// but if the width is the initial/default width, don't include it in the ColumnSizing
|
|
349
|
+
if (Width !== initialWidth) {
|
|
350
|
+
ColumnSizing[colId] = {
|
|
351
|
+
Width,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
348
354
|
});
|
|
349
355
|
if (!Object.keys(ColumnSizing).length) {
|
|
350
356
|
ColumnSizing = undefined;
|
|
@@ -1707,6 +1713,10 @@ export class LayoutManager extends LMEmitter {
|
|
|
1707
1713
|
}
|
|
1708
1714
|
}
|
|
1709
1715
|
isInPivotMode() {
|
|
1710
|
-
|
|
1716
|
+
// SSRM comes with its own pivot module implementation
|
|
1717
|
+
// see #ssrm_pivot_module
|
|
1718
|
+
const isModuleRegistered = this.gridApi.isModuleRegistered('PivotModule') ||
|
|
1719
|
+
this.gridApi.isModuleRegistered('ServerSideRowModelModule');
|
|
1720
|
+
return isModuleRegistered && this.gridApi.isPivotMode();
|
|
1711
1721
|
}
|
|
1712
1722
|
}
|