@adaptabletools/adaptable 23.0.6 → 23.0.8-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adaptabletools/adaptable",
3
- "version": "23.0.6",
3
+ "version": "23.0.8-canary.0",
4
4
  "description": "Powerful AG Grid extension which provides advanced, cutting-edge functionality to meet all DataGrid requirements",
5
5
  "keywords": [
6
6
  "web-components",
@@ -28,6 +28,13 @@ export interface DataChangeHistoryOptions<TData = any> {
28
28
  * @defaultValue true
29
29
  */
30
30
  showLastDataChangeOnly?: boolean;
31
+ /**
32
+ * How many data changes are held in State at any one time; when limit is reached, oldest change(s) are deleted from memory
33
+ *
34
+ * @defaultValue undefined (all data changes are logged)
35
+ * @noCodeItem
36
+ */
37
+ maxDataChangesInStore?: number;
31
38
  }
32
39
  /**
33
40
  * Built in `undo` or `clear` data change action
@@ -83,6 +83,7 @@ const DefaultAdaptableOptions = {
83
83
  showDataChange: undefined,
84
84
  changeHistoryButton: undefined,
85
85
  showLastDataChangeOnly: true,
86
+ maxDataChangesInStore: undefined,
86
87
  },
87
88
  dataImportOptions: {
88
89
  fileHandlers: undefined,
@@ -18,7 +18,6 @@ export interface WizardOptions {
18
18
  position?: WindowPosition;
19
19
  /**
20
20
  * Initial size (in pixels) of wizard (requires `popupType`: `'window'`)
21
- * `'window'`).
22
21
  *
23
22
  * @defaultValue Computed default sized for wizards
24
23
  */
@@ -41,13 +41,13 @@ export interface LayoutState extends BaseState {
41
41
  */
42
42
  Layouts: LayoutArray;
43
43
  }
44
- /**
45
- * Base object for both Table and Pivot Layouts
46
- */
47
44
  /**
48
45
  * How row groups are displayed in a Layout (maps to AG Grid `groupDisplayType`).
49
46
  */
50
47
  export type RowGroupDisplayType = 'single' | 'multi' | 'groupRows';
48
+ /**
49
+ * Base object for both Table and Pivot Layouts
50
+ */
51
51
  export interface LayoutBase extends AdaptableObject {
52
52
  /**
53
53
  * Name of the Layout as it appears in the Layout toolbar and tool panel
@@ -105,6 +105,9 @@ export interface LayoutBase extends AdaptableObject {
105
105
  * Position of the Grand Total Row in the Layout
106
106
  */
107
107
  GrandTotalRow?: 'top' | 'bottom' | 'pinnedTop' | 'pinnedBottom' | boolean;
108
+ /**
109
+ * How Row Groups are displayed: 'single' - one hierarchical group Column; 'multi' - a separate group Column per Row Grouped Column; 'groupRows' - full-width group rows (no group column); defaults to 'single'
110
+ */
108
111
  RowGroupDisplayType?: RowGroupDisplayType;
109
112
  }
110
113
  /**
@@ -10,16 +10,16 @@ export class DataChangeHistoryApiImpl extends ApiBase {
10
10
  if (currentMode === 'ACTIVE' && !forceReset) {
11
11
  return;
12
12
  }
13
- if (forceReset || currentMode === 'INACTIVE') {
14
- this.dispatchAction(DataChangeHistoryEnable());
15
- }
16
- else if (currentMode === 'SUSPENDED') {
13
+ if (currentMode === 'SUSPENDED' && !forceReset) {
17
14
  this.dispatchAction(DataChangeHistoryResume());
18
15
  }
16
+ else {
17
+ this.dispatchAction(DataChangeHistoryEnable());
18
+ }
19
19
  }
20
20
  deactivateDataChangeHistory() {
21
- if (this.getDataChangeHistoryMode() === 'ACTIVE' ||
22
- this.getDataChangeHistoryMode() === 'SUSPENDED') {
21
+ const currentMode = this.getDataChangeHistoryMode();
22
+ if (currentMode !== 'INACTIVE') {
23
23
  this.dispatchAction(DataChangeHistoryDisable());
24
24
  }
25
25
  }
@@ -39,7 +39,8 @@ export class DataChangeHistoryApiImpl extends ApiBase {
39
39
  }
40
40
  addDataChangeHistoryEntry(dataChangeInfo) {
41
41
  const uniqueKey = this.getDataChangeHistoryKey(dataChangeInfo);
42
- this.dispatchAction(DataChangeHistoryAdd(dataChangeInfo, uniqueKey));
42
+ const maxDataChangesInStore = this.getDataChangeHistoryOptions().maxDataChangesInStore;
43
+ this.dispatchAction(DataChangeHistoryAdd(dataChangeInfo, uniqueKey, maxDataChangesInStore));
43
44
  }
44
45
  undoDataChangeHistoryEntry(dataChangeInfo) {
45
46
  const uniqueKey = this.getDataChangeHistoryKey(dataChangeInfo);
@@ -65,10 +66,10 @@ export class DataChangeHistoryApiImpl extends ApiBase {
65
66
  const changedAt = dataChangeInfo.changedAt;
66
67
  const showLastDataChangeOnly = this.getDataChangeHistoryOptions().showLastDataChangeOnly;
67
68
  if (showLastDataChangeOnly) {
68
- return JSON.stringify({ columnId, primaryKeyValue });
69
+ return `${columnId}\u0000${primaryKeyValue}`;
69
70
  }
70
71
  else {
71
- return JSON.stringify({ columnId, primaryKeyValue, changedAt });
72
+ return `${columnId}\u0000${primaryKeyValue}\u0000${changedAt}`;
72
73
  }
73
74
  };
74
75
  }
@@ -36,8 +36,4 @@ export declare class LayoutInternalApi extends ApiBase {
36
36
  cloneLayout(layoutToClone: Layout): Omit<Layout, 'Name'>;
37
37
  getCurrentLayout_perfOptimized(): Layout | null;
38
38
  getCurrentLayoutRowGroupDisplayType(): LayoutBase['RowGroupDisplayType'];
39
- areAllGroupedColumnsFilterable(): {
40
- filter: boolean;
41
- floatingFilter: boolean;
42
- };
43
39
  }
@@ -187,25 +187,4 @@ export class LayoutInternalApi extends ApiBase {
187
187
  getCurrentLayoutRowGroupDisplayType() {
188
188
  return this.getLayoutApi().getCurrentLayout()?.RowGroupDisplayType ?? 'single';
189
189
  }
190
- areAllGroupedColumnsFilterable() {
191
- const groupedAgColumns = this.getAgGridApi().getRowGroupColumns();
192
- let allHaveFilter = true;
193
- let allHaveFloatingFilter = true;
194
- for (const column of groupedAgColumns) {
195
- if (!allHaveFilter && !allHaveFloatingFilter) {
196
- break;
197
- }
198
- const colDef = column.getColDef();
199
- if (allHaveFilter && !colDef.filter) {
200
- allHaveFilter = false;
201
- }
202
- if (allHaveFloatingFilter && !colDef.floatingFilter) {
203
- allHaveFloatingFilter = false;
204
- }
205
- }
206
- return {
207
- filter: allHaveFilter,
208
- floatingFilter: allHaveFloatingFilter,
209
- };
210
- }
211
190
  }
@@ -247,6 +247,7 @@ export interface DataChangeHistoryAction extends Redux.Action {
247
247
  uniqueKey: string;
248
248
  }
249
249
  export interface DataChangeHistoryAddAction extends DataChangeHistoryAction {
250
+ maxDataChanges?: number;
250
251
  }
251
252
  export interface DataChangeHistoryUndoAction extends DataChangeHistoryAction {
252
253
  }
@@ -324,7 +325,7 @@ export declare const CachedQueryAdd: (cachedQuery: CachedQuery) => CachedQueryAd
324
325
  export declare const CellSummaryChangeOperation: (cellSummaryOperation: SummaryOperation | string) => CellSummaryChangeOperationAction;
325
326
  export declare const LicenseShowWatermark: (text: string) => LicenseShowWatermarkAction;
326
327
  export declare const LicenseDisablePersistence: () => LicenseDisablePersistenceAction;
327
- export declare const DataChangeHistoryAdd: (changeInfo: CellDataChangedInfo, uniqueKey: string) => DataChangeHistoryAddAction;
328
+ export declare const DataChangeHistoryAdd: (changeInfo: CellDataChangedInfo, uniqueKey: string, maxDataChanges?: number) => DataChangeHistoryAddAction;
328
329
  export declare const DataChangeHistoryUndo: (changeInfo: CellDataChangedInfo, uniqueKey: string) => DataChangeHistoryUndoAction;
329
330
  export declare const DataChangeHistoryClearRow: (changeInfo: CellDataChangedInfo, uniqueKey: string) => DataChangeHistoryClearRowAction;
330
331
  export declare const DataChangeHistoryEnable: () => DataChangeHistoryEnableAction;
@@ -213,10 +213,11 @@ export const LicenseShowWatermark = (text) => ({
213
213
  export const LicenseDisablePersistence = () => ({
214
214
  type: LICENSE_DISABLE_PERSISTENCE,
215
215
  });
216
- export const DataChangeHistoryAdd = (changeInfo, uniqueKey) => ({
216
+ export const DataChangeHistoryAdd = (changeInfo, uniqueKey, maxDataChanges) => ({
217
217
  type: DATA_CHANGE_HISTORY_ADD,
218
218
  changeInfo,
219
219
  uniqueKey,
220
+ maxDataChanges,
220
221
  });
221
222
  export const DataChangeHistoryUndo = (changeInfo, uniqueKey) => ({
222
223
  type: DATA_CHANGE_HISTORY_UNDO,
@@ -372,6 +373,17 @@ const initialState = {
372
373
  inProgress: null,
373
374
  },
374
375
  };
376
+ const removeDataChangeHistoryLog = (state, uniqueKey) => {
377
+ const updatedDataChangeHistoryLogs = { ...state.DataChangeHistory.logs };
378
+ delete updatedDataChangeHistoryLogs[uniqueKey];
379
+ return {
380
+ ...state,
381
+ DataChangeHistory: {
382
+ ...state.DataChangeHistory,
383
+ logs: updatedDataChangeHistoryLogs,
384
+ },
385
+ };
386
+ };
375
387
  export const InternalReducer = (state = initialState, action) => {
376
388
  let alerts;
377
389
  let systemStatusMessages;
@@ -673,21 +685,16 @@ export const InternalReducer = (state = initialState, action) => {
673
685
  const cellDataChangedInfo = actionTypedAdd.changeInfo;
674
686
  const uniqueKey = actionTypedAdd.uniqueKey;
675
687
  const updatedDataChangeHistoryLogs = { ...state.DataChangeHistory.logs };
676
- updatedDataChangeHistoryLogs[uniqueKey] = cellDataChangedInfo;
677
- return {
678
- ...state,
679
- DataChangeHistory: {
680
- ...state.DataChangeHistory,
681
- logs: updatedDataChangeHistoryLogs,
682
- },
683
- };
684
- }
685
- case DATA_CHANGE_HISTORY_UNDO: {
686
- const actionTypedUndo = action;
687
- const cellDataChangedInfo = actionTypedUndo.changeInfo;
688
- const uniqueKey = actionTypedUndo.uniqueKey;
689
- const updatedDataChangeHistoryLogs = { ...state.DataChangeHistory.logs };
690
688
  delete updatedDataChangeHistoryLogs[uniqueKey];
689
+ updatedDataChangeHistoryLogs[uniqueKey] = cellDataChangedInfo;
690
+ const maxDataChanges = actionTypedAdd.maxDataChanges;
691
+ if (maxDataChanges != null && maxDataChanges >= 0) {
692
+ const keys = Object.keys(updatedDataChangeHistoryLogs);
693
+ const overflow = keys.length - maxDataChanges;
694
+ for (let i = 0; i < overflow; i++) {
695
+ delete updatedDataChangeHistoryLogs[keys[i]];
696
+ }
697
+ }
691
698
  return {
692
699
  ...state,
693
700
  DataChangeHistory: {
@@ -696,19 +703,10 @@ export const InternalReducer = (state = initialState, action) => {
696
703
  },
697
704
  };
698
705
  }
706
+ case DATA_CHANGE_HISTORY_UNDO:
699
707
  case DATA_CHANGE_HISTORY_CLEAR_ROW: {
700
- const actionTypedClearRow = action;
701
- const cellDataChangedInfo = actionTypedClearRow.changeInfo;
702
- const uniqueKey = actionTypedClearRow.uniqueKey;
703
- const updatedDataChangeHistoryLogs = { ...state.DataChangeHistory.logs };
704
- delete updatedDataChangeHistoryLogs[uniqueKey];
705
- return {
706
- ...state,
707
- DataChangeHistory: {
708
- ...state.DataChangeHistory,
709
- logs: updatedDataChangeHistoryLogs,
710
- },
711
- };
708
+ const { uniqueKey } = action;
709
+ return removeDataChangeHistoryLog(state, uniqueKey);
712
710
  }
713
711
  case DATA_CHANGE_HISTORY_ENABLE: {
714
712
  return {
@@ -29,7 +29,7 @@ export class DataChangeHistoryModule extends AdaptableModuleBase {
29
29
  this.api.internalApi
30
30
  .getDataService()
31
31
  .on('CellDataChanged', (cellDataChangedInfo) => {
32
- if (this.isListeningToCellDataChanges &&
32
+ if (this.shouldListenToDataChanges() &&
33
33
  this.isDataChangeLoggable(cellDataChangedInfo) &&
34
34
  !cellDataChangedInfo.preventEdit) {
35
35
  this.api.dataChangeHistoryApi.addDataChangeHistoryEntry(cellDataChangedInfo);
@@ -46,11 +46,17 @@ export const DataChangeHistoryTable = (props) => {
46
46
  },
47
47
  oldValue: {
48
48
  header: 'Previous',
49
- valueGetter: (params) => formatChangeHistoryCellValue(getChangeHistoryRowChangeInfo(params.data)?.oldValue),
49
+ valueGetter: (params) => {
50
+ const info = getChangeHistoryRowChangeInfo(params.data);
51
+ return formatChangeHistoryCellValue(info?.oldValue, info?.column, info?.rowNode, adaptable.api);
52
+ },
50
53
  },
51
54
  newValue: {
52
55
  header: 'New',
53
- valueGetter: (params) => formatChangeHistoryCellValue(getChangeHistoryRowChangeInfo(params.data)?.newValue),
56
+ valueGetter: (params) => {
57
+ const info = getChangeHistoryRowChangeInfo(params.data);
58
+ return formatChangeHistoryCellValue(info?.newValue, info?.column, info?.rowNode, adaptable.api);
59
+ },
54
60
  },
55
61
  changedAt: {
56
62
  header: 'Changed',
@@ -21,10 +21,9 @@ export const DataChangeHistoryViewPanelControl = (props) => {
21
21
  const handleOpenPopup = React.useCallback(() => {
22
22
  adaptable.api.settingsPanelApi.openSettingsPanel('DataChangeHistory');
23
23
  }, []);
24
- const dataChangeHistoryState = useSelector((state) => state.Internal.DataChangeHistory);
25
- const changeHistoryMode = dataChangeHistoryState.currentMode;
26
- const activationTime = dataChangeHistoryState.enableTime;
27
- const suspensionTime = dataChangeHistoryState.suspendTime;
24
+ const changeHistoryMode = useSelector((state) => state.Internal.DataChangeHistory.currentMode);
25
+ const activationTime = useSelector((state) => state.Internal.DataChangeHistory.enableTime);
26
+ const suspensionTime = useSelector((state) => state.Internal.DataChangeHistory.suspendTime);
28
27
  const enabled = changeHistoryMode === 'ACTIVE';
29
28
  const disabled = changeHistoryMode === 'INACTIVE';
30
29
  const suspended = changeHistoryMode === 'SUSPENDED';
@@ -1,5 +1,8 @@
1
+ import { IRowNode } from 'ag-grid-enterprise';
1
2
  import { CellDataChangedInfo } from '../../AdaptableState/Common/CellDataChangedInfo';
2
3
  import { IAdaptable } from '../../AdaptableInterfaces/IAdaptable';
4
+ import { AdaptableColumn } from '../../AdaptableState/Common/AdaptableColumn';
5
+ import { AdaptableApi } from '../../types';
3
6
  export interface DataChangeHistoryData {
4
7
  primaryKey: string;
5
8
  changeKey: string;
@@ -12,4 +15,23 @@ export declare const getChangeTriggerLabel: (changeInfo: CellDataChangedInfo) =>
12
15
  export declare const isValidChangeHistoryLogEntry: (changeInfo: CellDataChangedInfo | undefined) => changeInfo is CellDataChangedInfo;
13
16
  export declare const mapChangeHistoryRowData: (changeHistoryLog: Record<string, CellDataChangedInfo>, mainAdaptableInstance: IAdaptable) => DataChangeHistoryData[];
14
17
  export declare const getChangeHistoryRowChangeInfo: (rowData: Partial<DataChangeHistoryData> | undefined) => CellDataChangedInfo | undefined;
15
- export declare const formatChangeHistoryCellValue: (value: unknown) => string;
18
+ /**
19
+ * Format an old/new value for display in the Data Change History Monitor.
20
+ *
21
+ * If the changed column has a `DisplayFormat` configured (via Format Column),
22
+ * the value is run through the matching formatter so the History Log shows the
23
+ * same rendered text the user sees in the grid (e.g. a timestamp appears as
24
+ * `18:40:34` rather than the underlying `1751469622156`).
25
+ *
26
+ * If no `DisplayFormat` is scoped to the column, we fall back to `String(value)`
27
+ * — which preserves the previous behaviour for columns whose raw value already
28
+ * *is* the display value (e.g. plain numeric or string columns).
29
+ *
30
+ * Note: the `rowNode` passed here is the node captured when the change was
31
+ * recorded. Its data may have moved on since; that only matters for
32
+ * `CustomDisplayFormatters` that read other cells on the row — in which case
33
+ * the formatted value reflects the current state of that row, not the state at
34
+ * the time of the change. Any thrown error inside a formatter is swallowed and
35
+ * the raw value is shown, so the History Monitor never crashes on stale data.
36
+ */
37
+ export declare const formatChangeHistoryCellValue: (value: unknown, column: AdaptableColumn | undefined, rowNode: IRowNode | null | undefined, api: AdaptableApi) => string;
@@ -1,3 +1,4 @@
1
+ import { resolveDisplayFormat } from '../../AdaptableState/Common/AdaptableFormatPresets';
1
2
  const headerMap = new Map();
2
3
  export const getColumnHeaderLabel = (columnId, mainAdaptableInstance) => {
3
4
  if (!headerMap.has(columnId)) {
@@ -21,7 +22,7 @@ export const mapChangeHistoryRowData = (changeHistoryLog = {}, mainAdaptableInst
21
22
  changedColumnLabel: getColumnHeaderLabel(changeInfo.column.columnId, mainAdaptableInstance),
22
23
  changeInfo,
23
24
  }))
24
- .sort((a, b) => b.changeInfo.changedAt - a.changeInfo.changedAt);
25
+ .reverse();
25
26
  };
26
27
  export const getChangeHistoryRowChangeInfo = (rowData) => {
27
28
  if (!isValidChangeHistoryLogEntry(rowData?.changeInfo)) {
@@ -29,9 +30,37 @@ export const getChangeHistoryRowChangeInfo = (rowData) => {
29
30
  }
30
31
  return rowData.changeInfo;
31
32
  };
32
- export const formatChangeHistoryCellValue = (value) => {
33
+ export const formatChangeHistoryCellValue = (value, column, rowNode, api) => {
33
34
  if (value === null || value === undefined) {
34
35
  return '';
35
36
  }
36
- return String(value);
37
+ if (!column) {
38
+ return String(value);
39
+ }
40
+ const formatColumns = api.formatColumnApi.internalApi.getFormatColumnsWithDisplayFormatForColumn(column, { target: 'cell' });
41
+ const formatColumn = formatColumns[0];
42
+ if (!formatColumn) {
43
+ return String(value);
44
+ }
45
+ const resolvedFormat = resolveDisplayFormat(formatColumn.DisplayFormat);
46
+ if (!resolvedFormat) {
47
+ return String(value);
48
+ }
49
+ const { Formatter, Options } = resolvedFormat;
50
+ const nodeForFormatter = (rowNode ?? null);
51
+ try {
52
+ switch (Formatter) {
53
+ case 'DateFormatter':
54
+ return api.formatColumnApi.internalApi.getDateFormattedValue(value, nodeForFormatter, column, Options);
55
+ case 'NumberFormatter':
56
+ return String(api.formatColumnApi.internalApi.getNumberFormattedValue(value, nodeForFormatter, column, Options));
57
+ case 'StringFormatter':
58
+ return api.formatColumnApi.internalApi.getStringFormattedValue(value, nodeForFormatter, column, Options);
59
+ default:
60
+ return String(value);
61
+ }
62
+ }
63
+ catch {
64
+ return String(value);
65
+ }
37
66
  };
@@ -433,6 +433,7 @@ export class AdaptableAgGrid {
433
433
  this.logger.consoleError('Failed to initialize AG Grid.');
434
434
  return Promise.reject('Failed to initialize AG Grid.');
435
435
  }
436
+ this.agGridAdapter.setAgGridApi(agGridApi);
436
437
  this.layoutManager = new LayoutManager({
437
438
  gridApi: agGridApi,
438
439
  debugId: this.adaptableOptions.adaptableId,
@@ -455,7 +456,6 @@ export class AdaptableAgGrid {
455
456
  this.unmountLoadingScreen?.();
456
457
  perfInitAgGrid.end();
457
458
  initAgGridMarker.end();
458
- this.agGridAdapter.setAgGridApi(agGridApi);
459
459
  this.agGridAdapter.monkeyPatchingGridOptionsUpdates();
460
460
  this.agGridAdapter.monkeyPatchingAggColumnFilters();
461
461
  this.agGridAdapter.monkeyPatchingAggFuncLabels();
@@ -823,8 +823,7 @@ export class AdaptableAgGrid {
823
823
  handler: autoGroupFilterHandlerGenerator,
824
824
  };
825
825
  }
826
- const groupedColumnFilterConfig = this.api.layoutApi.internalApi.areAllGroupedColumnsFilterable();
827
- if (groupedColumnFilterConfig.filter) {
826
+ if (rowGroupDisplayType === 'multi') {
828
827
  return 'agGroupColumnFilter';
829
828
  }
830
829
  return original_autoGroupColumnDef?.filter;
@@ -843,12 +842,6 @@ export class AdaptableAgGrid {
843
842
  if (rowGroupDisplayType === 'single') {
844
843
  return true;
845
844
  }
846
- if (rowGroupDisplayType === 'multi') {
847
- const groupedColumnFilterConfig = this.api.layoutApi.internalApi.areAllGroupedColumnsFilterable();
848
- if (groupedColumnFilterConfig.floatingFilter) {
849
- return true;
850
- }
851
- }
852
845
  return original_autoGroupColumnDef?.floatingFilter;
853
846
  },
854
847
  enumerable: true,
@@ -1,4 +1,3 @@
1
- 'use client';
2
1
  import { jsx as _jsx } from "react/jsx-runtime";
3
2
  import * as React from 'react';
4
3
  import { cva } from 'class-variance-authority';
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: 1782917265348 || Date.now(),
4
- VERSION: "23.0.6" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1783187213468 || Date.now(),
4
+ VERSION: "23.0.8-canary.0" || '--current-version--',
5
5
  };