@adaptabletools/adaptable 20.2.0 → 20.2.2

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 +7 -7
  2. package/base.css.map +1 -1
  3. package/index.css +7 -7
  4. package/index.css.map +1 -1
  5. package/package.json +1 -1
  6. package/src/AdaptableOptions/QuickSearchOptions.d.ts +1 -1
  7. package/src/AdaptableOptions/StateOptions.d.ts +60 -15
  8. package/src/AdaptableState/Common/AdaptableColumn.d.ts +4 -0
  9. package/src/AdaptableState/FormatColumnState.d.ts +11 -6
  10. package/src/AdaptableState/LayoutState.d.ts +16 -2
  11. package/src/AdaptableState/QuickSearchState.d.ts +5 -5
  12. package/src/Api/Implementation/ColumnApiImpl.js +4 -2
  13. package/src/Api/Implementation/LayoutHelpers.d.ts +3 -0
  14. package/src/Api/Implementation/LayoutHelpers.js +76 -40
  15. package/src/Api/Implementation/QuickSearchApiImpl.d.ts +2 -2
  16. package/src/Api/Implementation/QuickSearchApiImpl.js +4 -4
  17. package/src/Api/Implementation/StateApiImpl.d.ts +1 -0
  18. package/src/Api/Implementation/StateApiImpl.js +6 -5
  19. package/src/Api/Internal/ColumnInternalApi.d.ts +1 -0
  20. package/src/Api/Internal/ColumnInternalApi.js +5 -0
  21. package/src/Api/Internal/FormatColumnInternalApi.d.ts +1 -1
  22. package/src/Api/Internal/FormatColumnInternalApi.js +8 -8
  23. package/src/Api/QuickSearchApi.d.ts +2 -2
  24. package/src/Api/StateApi.d.ts +9 -0
  25. package/src/Redux/ActionsReducers/QuickSearchRedux.d.ts +4 -4
  26. package/src/Redux/ActionsReducers/QuickSearchRedux.js +7 -7
  27. package/src/Redux/Store/AdaptableReduxLocalStorageEngine.js +14 -18
  28. package/src/Redux/Store/AdaptableStore.d.ts +2 -0
  29. package/src/Redux/Store/AdaptableStore.js +13 -5
  30. package/src/Redux/Store/Interface/IAdaptableStore.d.ts +1 -0
  31. package/src/Redux/Store/Interface/IStorageEngine.d.ts +4 -4
  32. package/src/Redux/Store/buildAdaptableStateFunctionConfig.d.ts +3 -0
  33. package/src/Redux/Store/buildAdaptableStateFunctionConfig.js +9 -0
  34. package/src/Utilities/ExpressionFunctions/observableExpressionFunctions.js +1 -1
  35. package/src/Utilities/Helpers/StyleHelper.d.ts +1 -1
  36. package/src/Utilities/Helpers/StyleHelper.js +11 -0
  37. package/src/Utilities/Services/LicenseService/index.js +1 -1
  38. package/src/Utilities/license/decode.js +1 -1
  39. package/src/View/CalculatedColumn/Wizard/CalculatedColumnExpressionWizardSection.js +1 -3
  40. package/src/View/Components/EntityRulesEditor/index.js +3 -3
  41. package/src/View/Components/ExpressionWizard.js +1 -1
  42. package/src/View/Components/StyleComponent.d.ts +1 -0
  43. package/src/View/Components/StyleComponent.js +2 -1
  44. package/src/View/Export/Wizard/ReportRowsWizardSection.js +1 -1
  45. package/src/View/GridFilter/GridFilterExpressionEditor.js +1 -1
  46. package/src/View/Layout/Wizard/sections/ColumnsSection.js +27 -8
  47. package/src/View/Layout/Wizard/sections/GridFilterSection.js +1 -1
  48. package/src/View/Layout/Wizard/sections/RowGroupingSection.js +4 -4
  49. package/src/View/License/LicenseWatermark.js +1 -1
  50. package/src/View/NamedQuery/Wizard/NamedQueryExpressionWizardSection.js +1 -1
  51. package/src/View/QuickSearch/QuickSearchInput.js +3 -2
  52. package/src/View/QuickSearch/QuickSearchPopup.d.ts +1 -1
  53. package/src/View/QuickSearch/QuickSearchPopup.js +7 -4
  54. package/src/agGrid/AdaptableAgGrid.js +22 -11
  55. package/src/agGrid/AgGridAdapter.js +6 -1
  56. package/src/agGrid/AgGridColumnAdapter.d.ts +1 -0
  57. package/src/agGrid/AgGridColumnAdapter.js +39 -17
  58. package/src/agGrid/AgGridExportAdapter.js +22 -10
  59. package/src/env.js +2 -2
  60. package/src/layout-manager/src/LayoutManagerModel.d.ts +17 -4
  61. package/src/layout-manager/src/index.d.ts +1 -1
  62. package/src/layout-manager/src/index.js +61 -18
  63. package/src/metamodel/adaptable.metamodel.d.ts +43 -16
  64. package/src/metamodel/adaptable.metamodel.js +1 -1
  65. package/src/types.d.ts +2 -2
  66. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -64,6 +64,78 @@ const errorOnce = (message) => {
64
64
  console.error(message);
65
65
  errorOnceMessages.set(message, true);
66
66
  };
67
+ export const getLayoutRowGroupValuesExceptionGroupKeys = (layout) => {
68
+ if (!layout.RowGroupValues) {
69
+ return [];
70
+ }
71
+ if (layout.RowGroupValues?.RowGroupDefaultBehavior === 'always-collapsed') {
72
+ return [];
73
+ }
74
+ if (layout.RowGroupValues?.RowGroupDefaultBehavior === 'always-expanded') {
75
+ return [];
76
+ }
77
+ if (Array.isArray(layout.RowGroupValues?.GroupKeys)) {
78
+ const currentGroupedColumns = (layout.RowGroupedColumns || []).join(',');
79
+ const matchingGroupKeys = layout.RowGroupValues.GroupKeys.find(({ RowGroupedColumns }) => {
80
+ return RowGroupedColumns.join(',') === currentGroupedColumns;
81
+ });
82
+ if (matchingGroupKeys) {
83
+ return matchingGroupKeys.ExceptionGroupKeys;
84
+ }
85
+ }
86
+ return layout.RowGroupValues.ExceptionGroupKeys || [];
87
+ };
88
+ export const toRowGroupValuesForLayoutState = (rowGroupValuesModel) => {
89
+ if (!rowGroupValuesModel) {
90
+ return undefined;
91
+ }
92
+ const rowGroupValuesState = {
93
+ RowGroupDefaultBehavior: rowGroupValuesModel.RowGroupDisplay,
94
+ };
95
+ if (rowGroupValuesModel.RowGroupDisplay === 'collapsed' ||
96
+ rowGroupValuesModel.RowGroupDisplay === 'expanded') {
97
+ if (rowGroupValuesModel.GroupKeys) {
98
+ rowGroupValuesState.GroupKeys =
99
+ rowGroupValuesModel.GroupKeys.map(({ RowGroupedColumns, Values }) => {
100
+ return {
101
+ RowGroupedColumns,
102
+ ExceptionGroupKeys: Values,
103
+ };
104
+ });
105
+ }
106
+ else {
107
+ rowGroupValuesState.ExceptionGroupKeys =
108
+ rowGroupValuesModel.Values;
109
+ }
110
+ }
111
+ return rowGroupValuesState;
112
+ };
113
+ export const toRowGroupValuesForLayoutModel = (rowGroupValuesState) => {
114
+ if (!rowGroupValuesState) {
115
+ return undefined;
116
+ }
117
+ if (rowGroupValuesState.RowGroupDefaultBehavior === 'always-collapsed' ||
118
+ rowGroupValuesState.RowGroupDefaultBehavior === 'always-expanded') {
119
+ return {
120
+ RowGroupDisplay: rowGroupValuesState.RowGroupDefaultBehavior,
121
+ };
122
+ }
123
+ if (rowGroupValuesState.GroupKeys) {
124
+ return {
125
+ RowGroupDisplay: rowGroupValuesState.RowGroupDefaultBehavior,
126
+ GroupKeys: rowGroupValuesState.GroupKeys.map(({ RowGroupedColumns, ExceptionGroupKeys }) => {
127
+ return {
128
+ RowGroupedColumns,
129
+ Values: ExceptionGroupKeys,
130
+ };
131
+ }),
132
+ };
133
+ }
134
+ return {
135
+ RowGroupDisplay: rowGroupValuesState.RowGroupDefaultBehavior,
136
+ Values: rowGroupValuesState.ExceptionGroupKeys || [],
137
+ };
138
+ };
67
139
  export const checkForDuplicateColumns = (layout) => {
68
140
  if (layout.TableColumns) {
69
141
  const set = new Set(layout.TableColumns);
@@ -97,17 +169,7 @@ export const tableLayoutToTableLayoutModel = (tableLayout) => {
97
169
  ColumnSorts: tableLayout.ColumnSorts,
98
170
  RowGroupedColumns: tableLayout.RowGroupedColumns,
99
171
  ColumnPinning: tableLayout.ColumnPinning,
100
- RowGroupValues: tableLayout.RowGroupValues
101
- ? tableLayout.RowGroupValues.RowGroupDefaultBehavior === 'always-collapsed' ||
102
- tableLayout.RowGroupValues.RowGroupDefaultBehavior === 'always-expanded'
103
- ? {
104
- RowGroupDisplay: tableLayout.RowGroupValues.RowGroupDefaultBehavior,
105
- }
106
- : {
107
- RowGroupDisplay: tableLayout.RowGroupValues.RowGroupDefaultBehavior,
108
- Values: tableLayout.RowGroupValues.ExceptionGroupKeys || [],
109
- }
110
- : undefined,
172
+ RowGroupValues: toRowGroupValuesForLayoutModel(tableLayout.RowGroupValues),
111
173
  ColumnGroupValues: tableLayout.ColumnGroupValues
112
174
  ? tableLayout.ColumnGroupValues.ColumnGroupDefaultBehavior === 'always-expanded' ||
113
175
  tableLayout.ColumnGroupValues.ColumnGroupDefaultBehavior === 'always-collapsed'
@@ -180,17 +242,7 @@ export const pivotLayoutToPivotLayoutModel = (pivotLayout) => {
180
242
  GrandTotalRow: pivotLayout.GrandTotalRow,
181
243
  PivotGrandTotal: pivotLayout.PivotGrandTotal,
182
244
  PivotColumnTotal: pivotLayout.PivotColumnTotal,
183
- RowGroupValues: pivotLayout.RowGroupValues
184
- ? pivotLayout.RowGroupValues.RowGroupDefaultBehavior === 'always-collapsed' ||
185
- pivotLayout.RowGroupValues.RowGroupDefaultBehavior === 'always-expanded'
186
- ? {
187
- RowGroupDisplay: pivotLayout.RowGroupValues.RowGroupDefaultBehavior,
188
- }
189
- : {
190
- RowGroupDisplay: pivotLayout.RowGroupValues.RowGroupDefaultBehavior,
191
- Values: pivotLayout.RowGroupValues.ExceptionGroupKeys || [],
192
- }
193
- : undefined,
245
+ RowGroupValues: toRowGroupValuesForLayoutModel(pivotLayout.RowGroupValues),
194
246
  ColumnGroupValues: pivotLayout.ColumnGroupValues
195
247
  ? pivotLayout.ColumnGroupValues.ColumnGroupDefaultBehavior === 'always-expanded' ||
196
248
  pivotLayout.ColumnGroupValues.ColumnGroupDefaultBehavior === 'always-collapsed'
@@ -295,15 +347,7 @@ export const tableLayoutModelToTableLayout = (layoutModel) => {
295
347
  delete tableLayout.ColumnPinning;
296
348
  }
297
349
  if (layoutModel.RowGroupValues) {
298
- tableLayout.RowGroupValues = {
299
- RowGroupDefaultBehavior: layoutModel.RowGroupValues.RowGroupDisplay,
300
- };
301
- if ((layoutModel.RowGroupValues.RowGroupDisplay === 'collapsed' ||
302
- layoutModel.RowGroupValues.RowGroupDisplay === 'expanded') &&
303
- layoutModel.RowGroupValues.Values) {
304
- // @ts-ignore
305
- tableLayout.RowGroupValues.ExceptionGroupKeys = layoutModel.RowGroupValues.Values;
306
- }
350
+ tableLayout.RowGroupValues = toRowGroupValuesForLayoutState(layoutModel.RowGroupValues);
307
351
  }
308
352
  else {
309
353
  delete tableLayout.RowGroupValues;
@@ -397,15 +441,7 @@ export const pivotLayoutModelToPivotLayout = (layoutModel) => {
397
441
  delete pivotLayout.PivotGroupedColumns;
398
442
  }
399
443
  if (layoutModel.RowGroupValues) {
400
- pivotLayout.RowGroupValues = {
401
- RowGroupDefaultBehavior: layoutModel.RowGroupValues.RowGroupDisplay,
402
- };
403
- if ((layoutModel.RowGroupValues.RowGroupDisplay === 'collapsed' ||
404
- layoutModel.RowGroupValues.RowGroupDisplay === 'expanded') &&
405
- layoutModel.RowGroupValues.Values) {
406
- // @ts-ignore
407
- pivotLayout.RowGroupValues.ExceptionGroupKeys = layoutModel.RowGroupValues.Values;
408
- }
444
+ pivotLayout.RowGroupValues = toRowGroupValuesForLayoutState(layoutModel.RowGroupValues);
409
445
  }
410
446
  else {
411
447
  delete pivotLayout.RowGroupValues;
@@ -9,10 +9,10 @@ export declare class QuickSearchApiImpl extends ApiBase implements QuickSearchAp
9
9
  gotoNextMatch(): void;
10
10
  gotoPreviousMatch(): void;
11
11
  getQuickSearchValue(): string;
12
- getQuickSearchStyle(): AdaptableStyle;
12
+ getQuickSearchCellMatchStyle(): AdaptableStyle;
13
13
  getQuickSearchTextMatchStyle(): AdaptableStyle | undefined;
14
14
  getQuickSearchCurrentTextMatchStyle(): AdaptableStyle | undefined;
15
- setQuickSearchStyle(style: AdaptableStyle): void;
15
+ setQuickSearchCellMatchStyle(style: AdaptableStyle): void;
16
16
  openQuickSearchSettingsPanel(): void;
17
17
  showFloatingQuickSearch(): void;
18
18
  hideFloatingQuickSearch(): void;
@@ -21,8 +21,8 @@ export class QuickSearchApiImpl extends ApiBase {
21
21
  getQuickSearchValue() {
22
22
  return this.getQuickSearchState().QuickSearchText;
23
23
  }
24
- getQuickSearchStyle() {
25
- return this.getQuickSearchState().Style;
24
+ getQuickSearchCellMatchStyle() {
25
+ return this.getQuickSearchState().CellMatchStyle;
26
26
  }
27
27
  getQuickSearchTextMatchStyle() {
28
28
  return this.getQuickSearchState().TextMatchStyle;
@@ -30,8 +30,8 @@ export class QuickSearchApiImpl extends ApiBase {
30
30
  getQuickSearchCurrentTextMatchStyle() {
31
31
  return this.getQuickSearchState().CurrentTextMatchStyle;
32
32
  }
33
- setQuickSearchStyle(style) {
34
- this.dispatchAction(QuickSearchRedux.QuickSearchSetStyle(style));
33
+ setQuickSearchCellMatchStyle(style) {
34
+ this.dispatchAction(QuickSearchRedux.QuickSearchSetCellMatchingStyle(style));
35
35
  }
36
36
  openQuickSearchSettingsPanel() {
37
37
  this.showModulePopup(ModuleConstants.QuickSearchModuleId);
@@ -40,6 +40,7 @@ export declare class StateApiImpl extends ApiBase implements StateApi {
40
40
  flushCurrentState?: boolean;
41
41
  progressIndicatorLabel?: string;
42
42
  }): Promise<void>;
43
+ persistAdaptableState(): Promise<AdaptableState>;
43
44
  getDescriptionForModule(module: AdaptableModule): string;
44
45
  getHelpPageForModule(module: AdaptableModule): string;
45
46
  getUserStateByStateKey(stateKey: AdaptableStateKey, returnJson?: boolean): BaseState | string;
@@ -23,6 +23,7 @@ import * as SmartEditRedux from '../../Redux/ActionsReducers/SmartEditRedux';
23
23
  import * as ThemeRedux from '../../Redux/ActionsReducers/ThemeRedux';
24
24
  import * as ToolPanelRedux from '../../Redux/ActionsReducers/ToolPanelRedux';
25
25
  import { logDeprecation } from '../../Utilities/logDeprecation';
26
+ import { buildAdaptableStateFunctionConfig } from '../../Redux/Store/buildAdaptableStateFunctionConfig';
26
27
  export class StateApiImpl extends ApiBase {
27
28
  configInit() {
28
29
  this.dispatchAction(InitState());
@@ -64,11 +65,7 @@ export class StateApiImpl extends ApiBase {
64
65
  this.getAdaptableStore()
65
66
  .saveStateNow(this._adaptable)
66
67
  .then(() => {
67
- const promise = clearStateFn({
68
- adaptableId: adaptableOptions.adaptableId,
69
- adaptableStateKey: adaptableOptions.adaptableStateKey,
70
- userName: adaptableOptions.userName,
71
- });
68
+ const promise = clearStateFn(buildAdaptableStateFunctionConfig(this._adaptable));
72
69
  promise.then(() => {
73
70
  this.setAdaptableStateKey(adaptableOptions.adaptableStateKey, {
74
71
  initialState: newInitialState || adaptableOptions.initialState,
@@ -164,6 +161,10 @@ export class StateApiImpl extends ApiBase {
164
161
  });
165
162
  });
166
163
  }
164
+ async persistAdaptableState() {
165
+ await this.getAdaptableStore().saveStateNow(this._adaptable);
166
+ return this.getAdaptableStore().getCurrentStorageState();
167
+ }
167
168
  getDescriptionForModule(module) {
168
169
  return this._adaptable.ModuleService.getModuleInfoByModule(module).Description;
169
170
  }
@@ -33,4 +33,5 @@ export declare class ColumnInternalApi extends ApiBase {
33
33
  isSpecialColumn(columnId: string, column?: AdaptableColumn): boolean;
34
34
  getColumnHeaderName(params: HeaderValueGetterParams): string;
35
35
  private buildColumnHeaderContext;
36
+ getQueryableColumnsForUIEditor(): AdaptableColumn[];
36
37
  }
@@ -282,4 +282,9 @@ export class ColumnInternalApi extends ApiBase {
282
282
  // if nothing matched, we skip this column[group]
283
283
  return 'skip';
284
284
  }
285
+ getQueryableColumnsForUIEditor() {
286
+ return this.getColumnApi()
287
+ .getQueryableColumns()
288
+ .filter((column) => !column.isGeneratedPivotResultColumn && !column.isGeneratedRowGroupColumn);
289
+ }
285
290
  }
@@ -77,7 +77,7 @@ export declare class FormatColumnInternalApi extends ApiBase {
77
77
  * @param scope Scope to check
78
78
  */
79
79
  getFormatColumnDefsForScope(scope: ColumnScope): AdaptablePredicateDef[];
80
- formatColumnWithColumnGroupStateShouldRender(formatColumn: FormatColumn, column: AdaptableColumn): boolean;
80
+ formatColumnWithColumnGroupScopeShouldRender(formatColumn: FormatColumn, column: AdaptableColumn): boolean;
81
81
  /**
82
82
  * Checks if format column is relevant for a given cell (intersection of given AdaptableColumn and RowNode)
83
83
  *
@@ -172,8 +172,8 @@ export class FormatColumnInternalApi extends ApiBase {
172
172
  .predicateApi.internalApi.getFormatColumnPredicateDefs(scope)
173
173
  .filter((predicateDef) => this.getColumnScopeApi().isScopeInScope(scope, predicateDef.columnScope));
174
174
  }
175
- formatColumnWithColumnGroupStateShouldRender(formatColumn, column) {
176
- if (!formatColumn.ColumnGroupState) {
175
+ formatColumnWithColumnGroupScopeShouldRender(formatColumn, column) {
176
+ if (!formatColumn.ColumnGroupScope) {
177
177
  return true;
178
178
  }
179
179
  const agGridApi = this.getAdaptableApi().agGridApi;
@@ -187,7 +187,7 @@ export class FormatColumnInternalApi extends ApiBase {
187
187
  if (!columnGroupParentForCurrentColumn) {
188
188
  return false;
189
189
  }
190
- const columnGroupState = columnGroupParentForCurrentColumn.isExpanded()
190
+ const columnGroupScope = columnGroupParentForCurrentColumn.isExpanded()
191
191
  ? 'Expanded'
192
192
  : 'Collapsed';
193
193
  const columnGroupLeafColumns = columnGroupParentForCurrentColumn.getLeafColumns();
@@ -195,13 +195,13 @@ export class FormatColumnInternalApi extends ApiBase {
195
195
  columnGroupLeafColumns.length === 1 &&
196
196
  columnGroupLeafColumns[0] === agGridColumn;
197
197
  if (columnIsTopLevel) {
198
- // for top-level columns don't apply formatColumns that have an explicit ColumnGroupState defined
198
+ // for top-level columns don't apply formatColumns that have an explicit ColumnGroupScope defined
199
199
  return false;
200
200
  }
201
- if (formatColumn.ColumnGroupState === 'Both') {
201
+ if (formatColumn.ColumnGroupScope === 'Both') {
202
202
  return true;
203
203
  }
204
- return formatColumn.ColumnGroupState === columnGroupState;
204
+ return formatColumn.ColumnGroupScope === columnGroupScope;
205
205
  }
206
206
  /**
207
207
  * Checks if format column is relevant for a given cell (intersection of given AdaptableColumn and RowNode)
@@ -233,8 +233,8 @@ export class FormatColumnInternalApi extends ApiBase {
233
233
  return false;
234
234
  }
235
235
  }
236
- if (formatColumn.ColumnGroupState &&
237
- !this.formatColumnWithColumnGroupStateShouldRender(formatColumn, column)) {
236
+ if (formatColumn.ColumnGroupScope &&
237
+ !this.formatColumnWithColumnGroupScopeShouldRender(formatColumn, column)) {
238
238
  return false;
239
239
  }
240
240
  if (!formatColumn.Rule) {
@@ -32,7 +32,7 @@ export interface QuickSearchApi {
32
32
  /**
33
33
  * Retrieves current Quick Search style
34
34
  */
35
- getQuickSearchStyle(): AdaptableStyle;
35
+ getQuickSearchCellMatchStyle(): AdaptableStyle;
36
36
  /**
37
37
  * Retrieves the style for the text match in the Quick Search
38
38
  */
@@ -45,7 +45,7 @@ export interface QuickSearchApi {
45
45
  * Sets style for Quick Search; can be name of (a provided) css style
46
46
  * @param style the style to use
47
47
  */
48
- setQuickSearchStyle(style: AdaptableStyle): void;
48
+ setQuickSearchCellMatchStyle(style: AdaptableStyle): void;
49
49
  /**
50
50
  * Opens Settings Panel with Quick Search section selected and visible
51
51
  */
@@ -210,4 +210,13 @@ export interface StateApi {
210
210
  * @param module Module which is Ready
211
211
  */
212
212
  dispatchStateReadyAction(module: AdaptableModule): void;
213
+ /**
214
+ * Persists the current Adaptable State to storage.
215
+ *
216
+ * This method first calls StateOption.saveState() to prepare the state
217
+ * and then StateOptions.persistState() to save it to the configured storage.
218
+ *
219
+ * @returns Promise<AdaptableState> - A promise that resolves to the persisted state
220
+ */
221
+ persistAdaptableState(): Promise<AdaptableState>;
213
222
  }
@@ -8,7 +8,7 @@ export declare const QUICK_SEARCH_RUN = "QUICK_SEARCH_RUN";
8
8
  /**
9
9
  * @ReduxAction Sets Quick Search style
10
10
  */
11
- export declare const QUICK_SEARCH_SET_STYLE = "QUICK_SEARCH_SET_STYLE";
11
+ export declare const QUICK_SEARCH_SET_CELL_MATCHING_STYLE = "QUICK_SEARCH_SET_CELL_MATCHING_STYLE";
12
12
  /**
13
13
  * @ReduxAction Quick Search Module is ready
14
14
  */
@@ -16,13 +16,13 @@ export declare const QUICK_SEARCH_READY = "QUICK_SEARCH_READY";
16
16
  export interface QuickSearchRunAction extends Redux.Action {
17
17
  quickSearchText: string;
18
18
  }
19
- export interface QuickSearchSetStyleAction extends Redux.Action {
20
- style: AdaptableStyle;
19
+ export interface QuickSearchSetMatchingCellStyleAction extends Redux.Action {
20
+ matchingCellStyle: AdaptableStyle;
21
21
  }
22
22
  export interface QuickSearchReadyAction extends Redux.Action {
23
23
  quickSearchState: QuickSearchState;
24
24
  }
25
25
  export declare const QuickSearchRun: (quickSearchText: string) => QuickSearchRunAction;
26
- export declare const QuickSearchSetStyle: (style: AdaptableStyle) => QuickSearchSetStyleAction;
26
+ export declare const QuickSearchSetCellMatchingStyle: (matchingCellStyle: AdaptableStyle) => QuickSearchSetMatchingCellStyleAction;
27
27
  export declare const QuickSearchReady: (quickSearchState: QuickSearchState) => QuickSearchReadyAction;
28
28
  export declare const QuickSearchReducer: Redux.Reducer<QuickSearchState>;
@@ -7,7 +7,7 @@ export const QUICK_SEARCH_RUN = 'QUICK_SEARCH_RUN';
7
7
  /**
8
8
  * @ReduxAction Sets Quick Search style
9
9
  */
10
- export const QUICK_SEARCH_SET_STYLE = 'QUICK_SEARCH_SET_STYLE';
10
+ export const QUICK_SEARCH_SET_CELL_MATCHING_STYLE = 'QUICK_SEARCH_SET_CELL_MATCHING_STYLE';
11
11
  /**
12
12
  * @ReduxAction Quick Search Module is ready
13
13
  */
@@ -16,9 +16,9 @@ export const QuickSearchRun = (quickSearchText) => ({
16
16
  type: QUICK_SEARCH_RUN,
17
17
  quickSearchText,
18
18
  });
19
- export const QuickSearchSetStyle = (style) => ({
20
- type: QUICK_SEARCH_SET_STYLE,
21
- style,
19
+ export const QuickSearchSetCellMatchingStyle = (matchingCellStyle) => ({
20
+ type: QUICK_SEARCH_SET_CELL_MATCHING_STYLE,
21
+ matchingCellStyle: matchingCellStyle,
22
22
  });
23
23
  export const QuickSearchReady = (quickSearchState) => ({
24
24
  type: QUICK_SEARCH_READY,
@@ -26,7 +26,7 @@ export const QuickSearchReady = (quickSearchState) => ({
26
26
  });
27
27
  const initialState = {
28
28
  QuickSearchText: EMPTY_STRING,
29
- Style: {
29
+ CellMatchStyle: {
30
30
  BackColor: QUICK_SEARCH_DEFAULT_BACK_COLOR,
31
31
  ForeColor: QUICK_SEARCH_DEFAULT_FORE_COLOR,
32
32
  },
@@ -37,9 +37,9 @@ export const QuickSearchReducer = (state = initialState, action) => {
37
37
  return Object.assign({}, state, {
38
38
  QuickSearchText: action.quickSearchText,
39
39
  });
40
- case QUICK_SEARCH_SET_STYLE:
40
+ case QUICK_SEARCH_SET_CELL_MATCHING_STYLE:
41
41
  return Object.assign({}, state, {
42
- Style: action.style,
42
+ CellMatchStyle: action.matchingCellStyle,
43
43
  });
44
44
  default:
45
45
  return state;
@@ -1,6 +1,7 @@
1
1
  import debounce from 'lodash/debounce';
2
2
  import { MergeStateFunction } from './AdaptableReduxMerger';
3
3
  import { AdaptableLogger } from '../../agGrid/AdaptableLogger';
4
+ import { buildAdaptableStateFunctionConfig } from './buildAdaptableStateFunctionConfig';
4
5
  const checkStatus = (response) => {
5
6
  const error = new Error(response.statusText);
6
7
  if (response.status >= 200 && response.status < 300) {
@@ -42,12 +43,8 @@ class AdaptableReduxLocalStorageEngine {
42
43
  setStateKey(adaptableStateKey) {
43
44
  this.adaptableStateKey = adaptableStateKey;
44
45
  }
45
- load(initialState = this.initialState) {
46
- return (this.loadState || loadState)({
47
- adaptableId: this.adaptableId,
48
- adaptableStateKey: this.adaptableStateKey,
49
- userName: this.userName,
50
- }).then((parsedJsonState) => {
46
+ load(adaptableInstance, initialState = this.initialState) {
47
+ return (this.loadState || loadState)(buildAdaptableStateFunctionConfig(adaptableInstance)).then((parsedJsonState) => {
51
48
  // we need to merge the Initial Adaptable State
52
49
  return Promise.resolve(initialState)
53
50
  .then((parsedInitialState) => {
@@ -56,20 +53,19 @@ class AdaptableReduxLocalStorageEngine {
56
53
  .catch((err) => AdaptableLogger.consoleErrorBase(`AdaptableId: ${this.adaptableId}`, err));
57
54
  });
58
55
  }
59
- save(state, getState) {
60
- return this.saveNow(state, getState);
56
+ save(adaptableInstance, state, actionName) {
57
+ return this.saveNow(adaptableInstance, state, actionName);
61
58
  }
62
- saveNow(state, getState) {
63
- const config = {
64
- adaptableId: this.adaptableId,
65
- adaptableStateKey: this.adaptableStateKey,
66
- userName: this.userName,
67
- };
68
- let result = state;
69
- if (getState) {
70
- result = getState(state, config);
59
+ saveNow(adaptableInstance, state, actionName) {
60
+ const config = buildAdaptableStateFunctionConfig(adaptableInstance);
61
+ config.actionName = actionName;
62
+ config.previousState = adaptableInstance.adaptableStore.getPreviousStorageState() || null;
63
+ let stateObject = structuredClone(state);
64
+ const getTransformedState = adaptableInstance.adaptableOptions.stateOptions.saveState;
65
+ if (getTransformedState) {
66
+ stateObject = getTransformedState(stateObject, config);
71
67
  }
72
- const promise = (this.persistState || persistState)(result, config)?.catch(rejectWithMessage);
68
+ const promise = (this.persistState || persistState)(stateObject, config)?.catch(rejectWithMessage);
73
69
  if (!(promise instanceof Promise)) {
74
70
  AdaptableLogger.consoleWarnBase(`AdaptableId: ${this.adaptableId}`, 'stateOptions.persistState should return a promise, it returned', 'Error', promise);
75
71
  }
@@ -26,6 +26,7 @@ export declare class AdaptableStore implements IAdaptableStore {
26
26
  private emitter;
27
27
  private storageEngine;
28
28
  private currentStorageState?;
29
+ private previousStorageState?;
29
30
  private loadStorageInProgress;
30
31
  private loadStateOnStartup;
31
32
  on: (eventName: string, callback: EmitterCallback) => (() => void);
@@ -39,6 +40,7 @@ export declare class AdaptableStore implements IAdaptableStore {
39
40
  constructor(adaptable: IAdaptable);
40
41
  destroy(): void;
41
42
  getCurrentStorageState(): AdaptableState;
43
+ getPreviousStorageState(): AdaptableState;
42
44
  saveStateNow(adaptable: IAdaptable): Promise<any>;
43
45
  loadStore: (config: LoadStoreConfig) => Promise<any>;
44
46
  }
@@ -39,6 +39,7 @@ import * as TeamSharingRedux from '../ActionsReducers/TeamSharingRedux';
39
39
  import * as ThemeRedux from '../ActionsReducers/ThemeRedux';
40
40
  import * as ToolPanelRedux from '../ActionsReducers/ToolPanelRedux';
41
41
  import { isAdaptableSharedEntity, isCustomSharedEntity, } from '../../AdaptableState/TeamSharingState';
42
+ import { buildAdaptableStateFunctionConfig } from './buildAdaptableStateFunctionConfig';
42
43
  export const INIT_STATE = 'INIT_STATE';
43
44
  export const LOAD_STATE = 'LOAD_STATE';
44
45
  const NON_PERSIST_ACTIONS = {
@@ -91,10 +92,10 @@ export class AdaptableStore {
91
92
  // START STATE LOAD
92
93
  this.loadStorageInProgress = true;
93
94
  return (this.Load = this.storageEngine
94
- .load(initialState)
95
+ .load(adaptable, initialState)
95
96
  .then((storedState) => {
96
97
  if (storedState && this.loadStateOnStartup) {
97
- this.TheStore.dispatch(LoadState(postProcessState(adaptable.adaptableOptions.stateOptions.applyState(storedState))));
98
+ this.TheStore.dispatch(LoadState(postProcessState(adaptable.adaptableOptions.stateOptions.applyState(storedState, buildAdaptableStateFunctionConfig(adaptable)))));
98
99
  }
99
100
  })
100
101
  .then(() => {
@@ -218,7 +219,11 @@ export class AdaptableStore {
218
219
  delete storageState[key];
219
220
  });
220
221
  this.currentStorageState = storageState;
221
- storageEngine.save(storageState, adaptable.adaptableOptions.stateOptions.saveState);
222
+ this.previousStorageState = { ...state };
223
+ NON_PERSISTENT_STORE_KEYS.forEach((key) => {
224
+ delete this.previousStorageState[key];
225
+ });
226
+ storageEngine.save(adaptable, storageState, action.type);
222
227
  }
223
228
  return finalState;
224
229
  };
@@ -242,10 +247,13 @@ export class AdaptableStore {
242
247
  getCurrentStorageState() {
243
248
  return this.currentStorageState;
244
249
  }
250
+ getPreviousStorageState() {
251
+ return this.previousStorageState;
252
+ }
245
253
  saveStateNow(adaptable) {
246
254
  const storageState = this.getCurrentStorageState();
247
255
  if (storageState) {
248
- return this.storageEngine.saveNow(storageState, adaptable.adaptableOptions.stateOptions.saveState);
256
+ return this.storageEngine.saveNow(adaptable, storageState, 'API_CALL_SAVE_STATE');
249
257
  }
250
258
  return Promise.resolve(true);
251
259
  }
@@ -458,7 +466,7 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
458
466
  * Use Case: We have updated an AdapTable Module that affects rendering
459
467
  * Action: We set up all columns again
460
468
  */
461
- case QuickSearchRedux.QUICK_SEARCH_SET_STYLE:
469
+ case QuickSearchRedux.QUICK_SEARCH_SET_CELL_MATCHING_STYLE:
462
470
  case FormatColumnRedux.FORMAT_COLUMN_ADD:
463
471
  case FormatColumnRedux.FORMAT_COLUMN_EDIT:
464
472
  case FormatColumnRedux.FORMAT_COLUMN_DELETE:
@@ -13,6 +13,7 @@ export interface IAdaptableStore {
13
13
  Load: Promise<any>;
14
14
  loadStore: (config: LoadStoreConfig) => Promise<any>;
15
15
  getCurrentStorageState: () => AdaptableState | void;
16
+ getPreviousStorageState: () => AdaptableState | void;
16
17
  saveStateNow: (adaptable: IAdaptable) => Promise<any>;
17
18
  on: (eventName: string, callback: (data?: any) => any) => () => void;
18
19
  onAny: (callback: (eventName: string, data?: any) => any) => () => void;
@@ -1,9 +1,9 @@
1
- import { AdaptableSaveStateFunction } from '../../../AdaptableOptions/StateOptions';
2
1
  import { AdaptableState } from '../../../AdaptableState/AdaptableState';
3
2
  import { InitialState } from '../../../AdaptableState/InitialState';
3
+ import { IAdaptable } from '../../../AdaptableInterfaces/IAdaptable';
4
4
  export default interface IStorageEngine {
5
- load(initialState?: string | InitialState): Promise<any>;
6
- save(state: AdaptableState, getEnhancedState?: AdaptableSaveStateFunction): Promise<any>;
7
- saveNow(state: AdaptableState, getEnhancedState?: AdaptableSaveStateFunction): Promise<any>;
5
+ load(adaptable: IAdaptable, initialState?: string | InitialState): Promise<any>;
6
+ save(adaptable: IAdaptable, state: AdaptableState, actionName: string): Promise<any>;
7
+ saveNow(adaptable: IAdaptable, state: AdaptableState, actionName: string): Promise<any>;
8
8
  setStateKey(stateKey: string): void;
9
9
  }
@@ -0,0 +1,3 @@
1
+ import { AdaptableStateFunctionConfig } from '../../AdaptableOptions/StateOptions';
2
+ import { IAdaptable } from '../../AdaptableInterfaces/IAdaptable';
3
+ export declare function buildAdaptableStateFunctionConfig(adaptable: IAdaptable): AdaptableStateFunctionConfig;
@@ -0,0 +1,9 @@
1
+ export function buildAdaptableStateFunctionConfig(adaptable) {
2
+ return {
3
+ adaptableId: adaptable.adaptableOptions.adaptableId,
4
+ adaptableStateKey: adaptable.adaptableOptions.adaptableStateKey,
5
+ userName: adaptable.adaptableOptions.userName,
6
+ adaptableApi: adaptable.api,
7
+ adaptableContext: adaptable.api?.optionsApi?.getAdaptableContext(),
8
+ };
9
+ }
@@ -291,7 +291,7 @@ const getDataChangedInfoStub = (context) => {
291
291
  const rowNode = rowNodeStub;
292
292
  if (rowNode) {
293
293
  const primaryKeyValue = context.adaptableApi.gridApi.getPrimaryKeyValueForRowNode(rowNode);
294
- const columnId = context.adaptableApi.columnApi.getQueryableColumns()[0]?.columnId;
294
+ const columnId = context.adaptableApi.columnApi.internalApi.getQueryableColumnsForUIEditor()[0]?.columnId;
295
295
  const oldValue = context.adaptableApi.gridApi.getCellRawValue(primaryKeyValue, columnId);
296
296
  const column = context.adaptableApi.columnApi.getColumnWithColumnId(columnId);
297
297
  const newValue = oldValue;
@@ -1,5 +1,5 @@
1
1
  import { AdaptableStyle } from '../../types';
2
- export declare const AgGridCellStyleProperties: readonly ["backgroundColor", "color", "fontWeight", "fontStyle", "fontSize", "borderColor"];
2
+ export declare const AgGridCellStyleProperties: readonly ["backgroundColor", "color", "fontWeight", "fontStyle", "fontSize", "borderColor", "--ab-dynamic-background-color", "--ab-dynamic-color", "--ab-dynamic-font-weight", "--ab-dynamic-font-style", "--ab-dynamic-font-size", "--ab-dynamic-text-decoration", "--ab-dynamic-border-radius", "--ab-dynamic-border-color"];
3
3
  export declare const normalizeStyleForAgGrid: (style: Record<string, any>) => {
4
4
  [x: string]: any;
5
5
  };
@@ -7,6 +7,17 @@ export const AgGridCellStyleProperties = [
7
7
  'fontStyle',
8
8
  'fontSize',
9
9
  'borderColor',
10
+ // needed for quick search
11
+ // as otherwise, the currentTextMatchStyle is not removed correctly
12
+ // from the cell when looping through the values, and the cell is no longer the current match
13
+ '--ab-dynamic-background-color',
14
+ '--ab-dynamic-color',
15
+ '--ab-dynamic-font-weight',
16
+ '--ab-dynamic-font-style',
17
+ '--ab-dynamic-font-size',
18
+ '--ab-dynamic-text-decoration',
19
+ '--ab-dynamic-border-radius',
20
+ '--ab-dynamic-border-color',
10
21
  ];
11
22
  // see https://github.com/AdaptableTools/adaptable/issues/2119
12
23
  // since v29 AG Grid ignores style properties with null or undefined values