@adaptabletools/adaptable 20.2.0 → 20.2.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 (47) 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/FormatColumnState.d.ts +11 -6
  9. package/src/AdaptableState/QuickSearchState.d.ts +3 -3
  10. package/src/Api/Implementation/ColumnApiImpl.js +3 -2
  11. package/src/Api/Implementation/StateApiImpl.d.ts +1 -0
  12. package/src/Api/Implementation/StateApiImpl.js +6 -5
  13. package/src/Api/Internal/ColumnInternalApi.d.ts +1 -0
  14. package/src/Api/Internal/ColumnInternalApi.js +5 -0
  15. package/src/Api/Internal/FormatColumnInternalApi.js +5 -5
  16. package/src/Api/StateApi.d.ts +9 -0
  17. package/src/Redux/Store/AdaptableReduxLocalStorageEngine.js +14 -18
  18. package/src/Redux/Store/AdaptableStore.d.ts +2 -0
  19. package/src/Redux/Store/AdaptableStore.js +12 -4
  20. package/src/Redux/Store/Interface/IAdaptableStore.d.ts +1 -0
  21. package/src/Redux/Store/Interface/IStorageEngine.d.ts +4 -4
  22. package/src/Redux/Store/buildAdaptableStateFunctionConfig.d.ts +3 -0
  23. package/src/Redux/Store/buildAdaptableStateFunctionConfig.js +9 -0
  24. package/src/Utilities/ExpressionFunctions/observableExpressionFunctions.js +1 -1
  25. package/src/Utilities/Helpers/StyleHelper.d.ts +1 -1
  26. package/src/Utilities/Helpers/StyleHelper.js +11 -0
  27. package/src/Utilities/Services/LicenseService/index.js +1 -1
  28. package/src/Utilities/license/decode.js +1 -1
  29. package/src/View/CalculatedColumn/Wizard/CalculatedColumnExpressionWizardSection.js +1 -3
  30. package/src/View/Components/EntityRulesEditor/index.js +3 -3
  31. package/src/View/Components/ExpressionWizard.js +1 -1
  32. package/src/View/Export/Wizard/ReportRowsWizardSection.js +1 -1
  33. package/src/View/GridFilter/GridFilterExpressionEditor.js +1 -1
  34. package/src/View/Layout/Wizard/sections/GridFilterSection.js +1 -1
  35. package/src/View/Layout/Wizard/sections/RowGroupingSection.js +2 -2
  36. package/src/View/License/LicenseWatermark.js +1 -1
  37. package/src/View/NamedQuery/Wizard/NamedQueryExpressionWizardSection.js +1 -1
  38. package/src/View/QuickSearch/QuickSearchInput.js +3 -2
  39. package/src/agGrid/AdaptableAgGrid.js +2 -2
  40. package/src/agGrid/AgGridColumnAdapter.d.ts +1 -0
  41. package/src/agGrid/AgGridColumnAdapter.js +29 -9
  42. package/src/agGrid/AgGridExportAdapter.js +22 -10
  43. package/src/env.js +2 -2
  44. package/src/metamodel/adaptable.metamodel.d.ts +33 -16
  45. package/src/metamodel/adaptable.metamodel.js +1 -1
  46. package/src/types.d.ts +1 -1
  47. package/tsconfig.esm.tsbuildinfo +1 -1
@@ -173,7 +173,7 @@ export class FormatColumnInternalApi extends ApiBase {
173
173
  .filter((predicateDef) => this.getColumnScopeApi().isScopeInScope(scope, predicateDef.columnScope));
174
174
  }
175
175
  formatColumnWithColumnGroupStateShouldRender(formatColumn, column) {
176
- if (!formatColumn.ColumnGroupState) {
176
+ if (!formatColumn.ColumnGroupScope) {
177
177
  return true;
178
178
  }
179
179
  const agGridApi = this.getAdaptableApi().agGridApi;
@@ -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 === columnGroupState;
205
205
  }
206
206
  /**
207
207
  * Checks if format column is relevant for a given cell (intersection of given AdaptableColumn and RowNode)
@@ -233,7 +233,7 @@ export class FormatColumnInternalApi extends ApiBase {
233
233
  return false;
234
234
  }
235
235
  }
236
- if (formatColumn.ColumnGroupState &&
236
+ if (formatColumn.ColumnGroupScope &&
237
237
  !this.formatColumnWithColumnGroupStateShouldRender(formatColumn, column)) {
238
238
  return false;
239
239
  }
@@ -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
  }
@@ -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
  }
@@ -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
@@ -1 +1 @@
1
- import{LicenseDisablePersistence as e,LicenseShowWatermark as a}from"../../../Redux/ActionsReducers/InternalRedux";import{PopupShowAlert as t}from"../../../Redux/ActionsReducers/PopupRedux";import i from"../../ObjectFactory";import s from"lodash/clamp";import{LicenseDocsLink as o}from"../../Constants/DocumentationLinkConstants";import{decode as n,GENERIC_APP_NAME as r}from"../../license/decode";import{shouldLogThankYouMessage as l}from"./shouldLogThankYouMessage";const c="sales@adaptabletools.com",p=10,d=864e5;export var LicenseValidityType;!function(e){e.INVALID_LICENSE="INVALID_LICENSE",e.NO_LICENSE="NO_LICENSE",e.NON_PRODUCTION_VALID="NON_PRODUCTION_VALID",e.NON_PRODUCTION_EXPIRED_IN_SCOPE="NON_PRODUCTION_EXPIRED_IN_SCOPE",e.NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE="NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE",e.COMMERCIAL_VALID="COMMERCIAL_VALID",e.COMMERCIAL_EXPIRED_IN_SCOPE="COMMERCIAL_EXPIRED_IN_SCOPE",e.COMMERCIAL_EXPIRED_OUT_OF_SCOPE="COMMERCIAL_EXPIRED_OUT_OF_SCOPE"}(LicenseValidityType||(LicenseValidityType={}));const h=()=>"undefined"!=typeof window?window.location.origin:"",E=()=>{const e=h(),[a,t,i]=Array.from(/(https):\/\/\d+\-\d+\-\d+\-(sandpack\.codesandbox\.io)/g.exec(e)||[]);return"https"===t&&"sandpack.codesandbox.io"===i},I=()=>{const e=h(),[a,t,i]=Array.from(/(https):\/\/\S+(\.csb\.app)/g.exec(e)||[]);return"https"===t&&".csb.app"===i},_=()=>{const e=h(),[a,t,i]=Array.from(/(https):\/\/\S+(\.adaptabletools\.com)/g.exec(e)||[]);return"https"===t&&".adaptabletools.com"===i};export class LicenseService{constructor(e,a,t){this.adaptable=e,this.licenseKey=a,this.packageDetails=t,this.adaptable=e,this.adaptable.api.eventApi.on("AdaptableReady",(()=>{requestAnimationFrame((()=>{this.adaptable.isDestroyed||this.init()}))}))}init(){let e=null;if(this.licenseKey)try{e=n(this.licenseKey)}catch(a){e=a}E()||I()||_()||this.handleLicenseValidation(e,this.getValidityType(e,this.packageDetails))}getValidityType(e,a){if(!e)return LicenseValidityType.NO_LICENSE;if(e instanceof Error)return LicenseValidityType.INVALID_LICENSE;const t=new Date(a.publishedAt),i=new Date(e.end),s=i<new Date,o=e.trial;let n=null;return n=s?i>t?o?LicenseValidityType.NON_PRODUCTION_EXPIRED_IN_SCOPE:LicenseValidityType.COMMERCIAL_EXPIRED_IN_SCOPE:o?LicenseValidityType.NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE:LicenseValidityType.COMMERCIAL_EXPIRED_OUT_OF_SCOPE:o?LicenseValidityType.NON_PRODUCTION_VALID:LicenseValidityType.COMMERCIAL_VALID,n}handleLicenseValidation(e,a){const t=new Date;t.setHours(0,0,0,0);let i=0;e instanceof Error||!e?.end||(i=Math.floor((e?.end?.getTime()-t.getTime())/d),i=s(i,0,1/0));let n="",h="";!e||e instanceof Error||!e.appName||e.appName==r||(n=e.appName,h=" for application [APP_NAME]");const E=(e,a=o,t=c,s=i,r=n)=>e.replace("[LINK]",a).replace("[EMAIL]",t).replace("[APP_NAME]",r).replace("[DAYS]",`${s}`);switch(a){case"NO_LICENSE":case"NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE":this.adaptable.logger.consoleLogByMessageType(E("This instance of AdapTable does not have a license, and some functionality has therefore been removed. In order to use a fully-featured version of AdapTable, please contact [EMAIL]. You can learn more about the different AdapTable license options at [LINK]."),"Error"),this.showNotification("No AdapTable License found."),this.showWatermark("This instance of AdapTable does not have a license, and some functionality has therefore been removed."),this.disableStatePersistence();break;case"INVALID_LICENSE":this.adaptable.logger.consoleLogByMessageType(E("This instance of AdapTable seems to use a corrupted License, and some functionality has therefore been removed. In order to use a fully-featured version of AdapTable, please contact [EMAIL]. You can learn more about the different AdapTable license options at [LINK]."),"Error"),this.showNotification("Corrupted AdapTable License found."),this.showWatermark("This instance of AdapTable has a corrupted License, and some functionality has therefore been removed."),this.disableStatePersistence();break;case"NON_PRODUCTION_VALID":this.adaptable.logger.consoleLogByMessageType(E("This AdapTable trial license expires in [DAYS] days. Please contact [EMAIL] to upgrade to a commercial version of AdapTable. You can learn more about the different AdapTable license options at [LINK]."),"Info");break;case"NON_PRODUCTION_EXPIRED_IN_SCOPE":this.adaptable.logger.consoleLogByMessageType(E("This AdapTable trial license has now expired. Please contact [EMAIL] to upgrade to a commercial version of AdapTable. You can learn more about the different AdapTable license options at [LINK]."),"Warning"),this.showWatermark("AdapTable License has expired");break;case"COMMERCIAL_VALID":if(i<=p)this.adaptable.logger.consoleLogByMessageType(E(`This AdapTable license${h} expires in [DAYS] days. Please contact [EMAIL] to renew (giving you access to Support and Updates)`),"Info");else try{l()&&this.adaptable.logger.consoleLogByMessageType(E(`Thank you for using a valid AdapTable license${h}. Your license will expire in [DAYS] days.`),"Info")}catch(e){}break;case"COMMERCIAL_EXPIRED_IN_SCOPE":this.adaptable.logger.consoleLogByMessageType(E(`This AdapTable license${h} has expired. Please contact [EMAIL] if you wish to renew (giving you access to Support and Updates)`),"Warning");break;case"COMMERCIAL_EXPIRED_OUT_OF_SCOPE":this.adaptable.logger.consoleLogByMessageType(E(`This AdapTable license${h} has expired. Adaptable version was published after the license expired. Please contact [EMAIL] if you wish to renew your license.`),"Error"),this.showNotification("Adaptable License has expired"),this.showWatermark("Adaptable License has expired")}}showNotification(e){this.adaptable.api.internalApi.dispatchReduxAction(t({alertType:"generic",header:"License Error",message:e,alertDefinition:i.CreateInternalAlertDefinitionForMessages("Error")}))}showWatermark(e){this.adaptable.api.internalApi.dispatchReduxAction(a(e))}disableStatePersistence(){this.adaptable.api.internalApi.dispatchReduxAction(e())}destroy(){}}
1
+ import{LicenseDisablePersistence as e,LicenseShowWatermark as a}from"../../../Redux/ActionsReducers/InternalRedux";import{PopupShowAlert as t}from"../../../Redux/ActionsReducers/PopupRedux";import i from"../../ObjectFactory";import s from"lodash/clamp";import{LicenseDocsLink as o}from"../../Constants/DocumentationLinkConstants";import{decode as n,GENERIC_APP_NAME as r}from"../../license/decode";import{shouldLogThankYouMessage as l}from"./shouldLogThankYouMessage";const c="sales@adaptabletools.com",p=10,d=864e5;export var LicenseValidityType;!function(e){e.INVALID_LICENSE="INVALID_LICENSE",e.NO_LICENSE="NO_LICENSE",e.NON_PRODUCTION_VALID="NON_PRODUCTION_VALID",e.NON_PRODUCTION_EXPIRED_IN_SCOPE="NON_PRODUCTION_EXPIRED_IN_SCOPE",e.NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE="NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE",e.COMMERCIAL_VALID="COMMERCIAL_VALID",e.COMMERCIAL_EXPIRED_IN_SCOPE="COMMERCIAL_EXPIRED_IN_SCOPE",e.COMMERCIAL_EXPIRED_OUT_OF_SCOPE="COMMERCIAL_EXPIRED_OUT_OF_SCOPE"}(LicenseValidityType||(LicenseValidityType={}));const h=()=>"undefined"!=typeof window?window.location.origin:"",E=()=>{const e=h(),[a,t,i]=Array.from(/(https):\/\/\d+\-\d+\-\d+\-(sandpack\.codesandbox\.io)/g.exec(e)||[]);return"https"===t&&"sandpack.codesandbox.io"===i},I=()=>{const e=h(),[a,t,i]=Array.from(/(https):\/\/\S+(\.csb\.app)/g.exec(e)||[]);return"https"===t&&".csb.app"===i},_=()=>{const e=h(),[a,t,i]=Array.from(/(https):\/\/\S+(\.adaptabletools\.com)/g.exec(e)||[]);return"https"===t&&".adaptabletools.com"===i};export class LicenseService{constructor(e,a,t){this.adaptable=e,this.licenseKey=a,this.packageDetails=t,this.adaptable=e,this.adaptable.api.eventApi.on("AdaptableReady",()=>{requestAnimationFrame(()=>{this.adaptable.isDestroyed||this.init()})})}init(){let e=null;if(this.licenseKey)try{e=n(this.licenseKey)}catch(a){e=a}E()||I()||_()||this.handleLicenseValidation(e,this.getValidityType(e,this.packageDetails))}getValidityType(e,a){if(!e)return LicenseValidityType.NO_LICENSE;if(e instanceof Error)return LicenseValidityType.INVALID_LICENSE;const t=new Date(a.publishedAt),i=new Date(e.end),s=i<new Date,o=e.trial;let n=null;return n=s?i>t?o?LicenseValidityType.NON_PRODUCTION_EXPIRED_IN_SCOPE:LicenseValidityType.COMMERCIAL_EXPIRED_IN_SCOPE:o?LicenseValidityType.NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE:LicenseValidityType.COMMERCIAL_EXPIRED_OUT_OF_SCOPE:o?LicenseValidityType.NON_PRODUCTION_VALID:LicenseValidityType.COMMERCIAL_VALID,n}handleLicenseValidation(e,a){const t=new Date;t.setHours(0,0,0,0);let i=0;e instanceof Error||!e?.end||(i=Math.floor((e?.end?.getTime()-t.getTime())/d),i=s(i,0,1/0));let n="",h="";!e||e instanceof Error||!e.appName||e.appName==r||(n=e.appName,h=" for application [APP_NAME]");const E=(e,a=o,t=c,s=i,r=n)=>e.replace("[LINK]",a).replace("[EMAIL]",t).replace("[APP_NAME]",r).replace("[DAYS]",`${s}`);switch(a){case"NO_LICENSE":case"NON_PRODUCTION_EXPIRED_OUT_OF_SCOPE":this.adaptable.logger.consoleLogByMessageType(E("This instance of AdapTable does not have a license, and some functionality has therefore been removed. In order to use a fully-featured version of AdapTable, please contact [EMAIL]. You can learn more about the different AdapTable license options at [LINK]."),"Error"),this.showNotification("No AdapTable License found."),this.showWatermark("This instance of AdapTable does not have a license, and some functionality has therefore been removed."),this.disableStatePersistence();break;case"INVALID_LICENSE":this.adaptable.logger.consoleLogByMessageType(E("This instance of AdapTable seems to use a corrupted License, and some functionality has therefore been removed. In order to use a fully-featured version of AdapTable, please contact [EMAIL]. You can learn more about the different AdapTable license options at [LINK]."),"Error"),this.showNotification("Corrupted AdapTable License found."),this.showWatermark("This instance of AdapTable has a corrupted License, and some functionality has therefore been removed."),this.disableStatePersistence();break;case"NON_PRODUCTION_VALID":this.adaptable.logger.consoleLogByMessageType(E("This AdapTable trial license expires in [DAYS] days. Please contact [EMAIL] to upgrade to a commercial version of AdapTable. You can learn more about the different AdapTable license options at [LINK]."),"Info");break;case"NON_PRODUCTION_EXPIRED_IN_SCOPE":this.adaptable.logger.consoleLogByMessageType(E("This AdapTable trial license has now expired. Please contact [EMAIL] to upgrade to a commercial version of AdapTable. You can learn more about the different AdapTable license options at [LINK]."),"Warning"),this.showWatermark("AdapTable License has expired");break;case"COMMERCIAL_VALID":if(i<=p)this.adaptable.logger.consoleLogByMessageType(E(`This AdapTable license${h} expires in [DAYS] days. Please contact [EMAIL] to renew (giving you access to Support and Updates)`),"Info");else try{l()&&this.adaptable.logger.consoleLogByMessageType(E(`Thank you for using a valid AdapTable license${h}. Your license will expire in [DAYS] days.`),"Info")}catch(e){}break;case"COMMERCIAL_EXPIRED_IN_SCOPE":this.adaptable.logger.consoleLogByMessageType(E(`This AdapTable license${h} has expired. Please contact [EMAIL] if you wish to renew (giving you access to Support and Updates)`),"Warning");break;case"COMMERCIAL_EXPIRED_OUT_OF_SCOPE":this.adaptable.logger.consoleLogByMessageType(E(`This AdapTable license${h} has expired. Adaptable version was published after the license expired. Please contact [EMAIL] if you wish to renew your license.`),"Error"),this.showNotification("Adaptable License has expired"),this.showWatermark("Adaptable License has expired")}}showNotification(e){this.adaptable.api.internalApi.dispatchReduxAction(t({alertType:"generic",header:"License Error",message:e,alertDefinition:i.CreateInternalAlertDefinitionForMessages("Error")}))}showWatermark(e){this.adaptable.api.internalApi.dispatchReduxAction(a(e))}disableStatePersistence(){this.adaptable.api.internalApi.dispatchReduxAction(e())}destroy(){}}
@@ -1 +1 @@
1
- import{compute_string as e}from"./hashing";const t=()=>new Error("Invalid License");export const GENERIC_APP_NAME="GenericAdaptableApp";export const fieldsToLicenseDetails=e=>{const r=e.reduce(((e,t)=>(e.set(t.name,t.value),e)),new Map),a={start:new Date(r.get("StartDate")),end:new Date(r.get("EndDate")),owner:r.get("Owner"),appName:r.get("AppName")||GENERIC_APP_NAME,timestamp:r.get("TS")?Number(r.get("TS")):0,trial:"true"===r.get("Trial"),ref:r.get("Ref")??""};if(!(a.start&&a.end&&a.owner&&"boolean"==typeof a.trial&&a.ref))throw t();return a};export const decode=r=>{let a="",n=r.split("|").map((e=>{let[t,r]=e.split("=");return"C"===t&&(a=r),{name:t,value:r}}));if(!a)throw t();const o=a.split(",").reverse(),s=o.pop();o.forEach(((r,a)=>{const o=n[a];if(e(o.value)!==r)throw t()}));const p=[...n];p.pop();const i=p.map((e=>`${e.name}=${e.value}`)).join("|");if(e(i)!==s)throw t();return n=n.map((e=>({...e,value:decodeURI(e.value)}))),fieldsToLicenseDetails(n)};
1
+ import{compute_string as e}from"./hashing";const t=()=>new Error("Invalid License");export const GENERIC_APP_NAME="GenericAdaptableApp";export const fieldsToLicenseDetails=e=>{const r=e.reduce((e,t)=>(e.set(t.name,t.value),e),new Map),a={start:new Date(r.get("StartDate")),end:new Date(r.get("EndDate")),owner:r.get("Owner"),appName:r.get("AppName")||GENERIC_APP_NAME,timestamp:r.get("TS")?Number(r.get("TS")):0,trial:"true"===r.get("Trial"),ref:r.get("Ref")??""};if(!(a.start&&a.end&&a.owner&&"boolean"==typeof a.trial&&a.ref))throw t();return a};export const decode=r=>{let a="",n=r.split("|").map(e=>{let[t,r]=e.split("=");return"C"===t&&(a=r),{name:t,value:r}});if(!a)throw t();const o=a.split(",").reverse(),s=o.pop();o.forEach((r,a)=>{const o=n[a];if(e(o.value)!==r)throw t()});const p=[...n];p.pop();const i=p.map(e=>`${e.name}=${e.value}`).join("|");if(e(i)!==s)throw t();return n=n.map(e=>({...e,value:decodeURI(e.value)})),fieldsToLicenseDetails(n)};
@@ -52,9 +52,7 @@ export const CalculatedColumnExpressionWizardSection = (props) => {
52
52
  return 'quantileAggregatedScalar';
53
53
  }
54
54
  };
55
- const columns = api.columnApi
56
- .getQueryableColumns()
57
- .filter((c) => !c.isGeneratedPivotResultColumn);
55
+ const columns = api.columnApi.internalApi.getQueryableColumnsForUIEditor();
58
56
  return (React.createElement(Tabs, { autoFocus: false, height: "100%" },
59
57
  React.createElement(Tabs.Tab, null, Humanize(props.expressionType)),
60
58
  React.createElement(Tabs.Content, null, (() => {
@@ -147,13 +147,13 @@ export const EntityRulesEditor = (props) => {
147
147
  React.createElement(EntityRulePredicatesEditor, { enablePredicateColumnId: props.enablePredicateColumnId, data: data, descriptions: descriptions, predicateDefs: filteredPredicateDefs, getPredicateDefsForColId: props.getPredicateDefsForColId, onChange: props.onChange }))) : null,
148
148
  showBoolean ? (React.createElement(QueryTab, { showRadio: showRadioButtons, value: "BooleanExpression", type: type, label: "Boolean" })) : null,
149
149
  showBoolean ? (React.createElement(Tabs.Content, { "data-name": "BooleanExpression", value: 'BooleanExpression' }, (() => {
150
- const editor = (React.createElement(ExpressionEditor, { type: 'boolean', module: module, value: data.Rule?.BooleanExpression, onChange: setBooleanExpression, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api, showQueryBuilder: props.showQueryBuilder }));
150
+ const editor = (React.createElement(ExpressionEditor, { type: 'boolean', module: module, value: data.Rule?.BooleanExpression, onChange: setBooleanExpression, initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api, showQueryBuilder: props.showQueryBuilder }));
151
151
  return props.showQueryBuilder ? React.createElement(Panel, null, editor) : editor;
152
152
  })())) : null,
153
153
  showObservable ? (React.createElement(QueryTab, { showRadio: showRadioButtons, value: "ObservableExpression", type: type, label: "Observable" })) : null,
154
154
  showObservable ? (React.createElement(Tabs.Content, { "data-name": "ObservableExpression", value: 'ObservableExpression' },
155
- React.createElement(ExpressionEditor, { type: 'observable', module: module, value: data.Rule?.ObservableExpression, onChange: setReactiveExpression, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }))) : null,
155
+ React.createElement(ExpressionEditor, { type: 'observable', module: module, value: data.Rule?.ObservableExpression, onChange: setReactiveExpression, initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }))) : null,
156
156
  showAggregation ? (React.createElement(QueryTab, { showRadio: showRadioButtons, value: "AggregatedBooleanExpression", type: type, label: "Aggregated Boolean" })) : null,
157
157
  showAggregation ? (React.createElement(Tabs.Content, { "data-name": "AggregatedBooleanExpression", value: 'AggregatedBooleanExpression' },
158
- React.createElement(ExpressionEditor, { type: 'aggregatedBoolean', module: module, value: data.Rule?.AggregatedBooleanExpression, onChange: setAggregationExpression, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }))) : null)));
158
+ React.createElement(ExpressionEditor, { type: 'aggregatedBoolean', module: module, value: data.Rule?.AggregatedBooleanExpression, onChange: setAggregationExpression, initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }))) : null)));
159
159
  };
@@ -27,7 +27,7 @@ export class ExpressionWizard extends React.Component {
27
27
  render() {
28
28
  const initialData = useMemo(() => this.props.api.internalApi.getQueryPreviewData(), []);
29
29
  return (React.createElement(React.Fragment, null,
30
- React.createElement(ExpressionEditor, { type: 'boolean', module: NamedQueryModuleId, value: this.state.expression, onChange: this.handleCustomExpressionChange, initialData: initialData, columns: this.props.api.columnApi.getQueryableColumns(), fields: this.props.api.expressionApi.internalApi.getAvailableFields(), namedQueries: this.props.api.namedQueryApi.getNamedQueries(), api: this.props.api }),
30
+ React.createElement(ExpressionEditor, { type: 'boolean', module: NamedQueryModuleId, value: this.state.expression, onChange: this.handleCustomExpressionChange, initialData: initialData, columns: this.props.api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: this.props.api.expressionApi.internalApi.getAvailableFields(), namedQueries: this.props.api.namedQueryApi.getNamedQueries(), api: this.props.api }),
31
31
  ' ',
32
32
  React.createElement(Flex, { flexDirection: "row", padding: 1, marginBottom: 2, marginLeft: 1, alignItems: "center", "data-name": "expression-wizard-save-option" },
33
33
  React.createElement(CheckBox, { marginLeft: 2, disabled: !this.isValidExpression(), marginBottom: 2, checked: this.state.saveToNamedQueries, onChange: (checked) => this.setState({
@@ -70,5 +70,5 @@ export const ReportRowsWizardSection = (props) => {
70
70
  BooleanExpression,
71
71
  },
72
72
  });
73
- }, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api })))));
73
+ }, initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api })))));
74
74
  };
@@ -88,7 +88,7 @@ export const GridFilterExpressionEditor = (props) => {
88
88
  },
89
89
  } },
90
90
  React.createElement(Flex, { height: "100%", flexDirection: "column" },
91
- React.createElement(ExpressionEditor, { ...expressionEditorProps, type: 'boolean', module: GridFilterModuleId, value: expression, onChange: (expression) => setExpression(expression), initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }),
91
+ React.createElement(ExpressionEditor, { ...expressionEditorProps, type: 'boolean', module: GridFilterModuleId, value: expression, onChange: (expression) => setExpression(expression), initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }),
92
92
  React.createElement(Flex, { flexDirection: "row", padding: 1, alignItems: "center" },
93
93
  props.onDismiss && (React.createElement(SimpleButton, { margin: 1, variant: "text", "data-name": "action-close", onClick: () => {
94
94
  props.onDismiss();
@@ -32,6 +32,6 @@ export const GridFilterSection = (props) => {
32
32
  Expression: expression,
33
33
  },
34
34
  });
35
- }, initialData: initialData, columns: api.columnApi.getQueryableColumns().filter((c) => !c.isGeneratedPivotResultColumn), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }));
35
+ }, initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }));
36
36
  return React.createElement("div", null, expressionEditorContent);
37
37
  };
@@ -19,8 +19,8 @@ export const RowGroupingSectionSummary = () => {
19
19
  React.createElement(Tag, null, "Row Grouping is not available in Tree Grids")));
20
20
  }
21
21
  return (React.createElement(Box, { display: 'flex', flexDirection: 'row' }, layout.RowGroupedColumns?.length ? (layout.RowGroupedColumns.map((columnId) => {
22
- return (React.createElement(Box, { mb: 2, mr: 2 },
23
- React.createElement(Tag, { key: columnId }, adaptable.api.columnApi.getFriendlyNameForColumnId(columnId))));
22
+ return (React.createElement(Box, { key: columnId, mb: 2, mr: 2 },
23
+ React.createElement(Tag, null, adaptable.api.columnApi.getFriendlyNameForColumnId(columnId))));
24
24
  })) : (React.createElement(Tag, null, "No Row Grouping"))));
25
25
  };
26
26
  export const RowGroupBehaviorSection = (props) => {
@@ -1 +1 @@
1
- import*as e from"react";import{Logo as t}from"../../components/Logo";import{Flex as r}from"rebass";const o={border:"1px solid var(--ab-color-error)",padding:"5px",fontWeight:600,margin:"5px",fontSize:"14px",alignItems:"center",color:"var(--ab-color-text-on-defaultbackground)",background:"var(--ab-color-defaultbackground)"},n=e=>{const t=[["display","none"],["opacity","0"],["position","absolute"],["position","fixed"],["position","relative"],["visibility","hidden"]];for(const[r,o]of t)if(e.style[r]===o)return!1;return!0};export const LicenseWatermark=i=>{const l=e.useRef(null);return e.useEffect((()=>{const e=setInterval((()=>{l.current?.isConnected||alert("It is not allowed to remove the Adaptable watermark."),n(l.current)||alert("It is not allowed to modify the Adaptable watermark."),l?.current?.style&&(l.current.style.border=o.border,l.current.style.padding=o.padding,l.current.style.fontWeight=`${o.fontWeight}`,l.current.style.margin=o.margin,l.current.style.fontSize=o.fontSize,l.current.style.color=o.color,l.current.style.background=o.background,l.current.style.display="flex",l.current.style.position="static",l.current.style.opacity="1",l.current.style.visibility="visible")}),5e3);return()=>clearTimeout(e)}),[]),e.createElement(r,{style:o,ref:l},e.createElement(t,{style:{marginRight:10}}),e.createElement("div",null,i.children))};
1
+ import*as e from"react";import{Logo as t}from"../../components/Logo";import{Flex as r}from"rebass";const o={border:"1px solid var(--ab-color-error)",padding:"5px",fontWeight:600,margin:"5px",fontSize:"14px",alignItems:"center",color:"var(--ab-color-text-on-defaultbackground)",background:"var(--ab-color-defaultbackground)"},n=e=>{const t=[["display","none"],["opacity","0"],["position","absolute"],["position","fixed"],["position","relative"],["visibility","hidden"]];for(const[r,o]of t)if(e.style[r]===o)return!1;return!0};export const LicenseWatermark=i=>{const l=e.useRef(null);return e.useEffect(()=>{const e=setInterval(()=>{l.current?.isConnected||alert("It is not allowed to remove the Adaptable watermark."),n(l.current)||alert("It is not allowed to modify the Adaptable watermark."),l?.current?.style&&(l.current.style.border=o.border,l.current.style.padding=o.padding,l.current.style.fontWeight=`${o.fontWeight}`,l.current.style.margin=o.margin,l.current.style.fontSize=o.fontSize,l.current.style.color=o.color,l.current.style.background=o.background,l.current.style.display="flex",l.current.style.position="static",l.current.style.opacity="1",l.current.style.visibility="visible")},5e3);return()=>clearTimeout(e)},[]),e.createElement(r,{style:o,ref:l},e.createElement(t,{style:{marginRight:10}}),e.createElement("div",null,i.children))};
@@ -26,5 +26,5 @@ export const NamedQueryExpressionWizardSection = (props) => {
26
26
  const initialData = useMemo(() => api.internalApi.getQueryPreviewData(), []);
27
27
  return (React.createElement(ExpressionEditor, { allowSaveNamedQuery: false, showQueryBuilder: true, type: 'boolean', module: moduleInfo.ModuleName, value: data.BooleanExpression, onChange: (BooleanExpression) => {
28
28
  props.onChange({ ...data, BooleanExpression });
29
- }, initialData: initialData, columns: api.columnApi.getQueryableColumns(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }));
29
+ }, initialData: initialData, columns: api.columnApi.internalApi.getQueryableColumnsForUIEditor(), fields: api.expressionApi.internalApi.getAvailableFields(), namedQueries: api.namedQueryApi.getNamedQueries(), api: api }));
30
30
  };
@@ -12,11 +12,12 @@ export const QuickSearchInput = (props) => {
12
12
  const QuickSearchText = useSelector((state) => state.QuickSearch.QuickSearchText);
13
13
  const dispatch = useDispatch();
14
14
  const onRunQuickSearch = React.useCallback((newQuickSearchText) => dispatch(QuickSearchRedux.QuickSearchRun(newQuickSearchText)), []);
15
+ const isServerSideRowModel = adaptable.api.gridApi.getAgGridRowModelType() === 'serverSide';
15
16
  const [searchText, search] = useQuickSearchDebounced({
16
17
  QuickSearchText,
17
18
  onRunQuickSearch,
18
19
  });
19
- return (React.createElement(AdaptableFormControlTextClear, { "aria-label": 'Quick Search', type: "text", autoFocus: props.autoFocus, placeholder: adaptable.api.optionsApi.getQuickSearchOptions().quickSearchPlaceholder, className: join('ab-DashboardToolbar__QuickSearch__text', props.className), value: searchText, OnTextChange: search, style: { height: '100%' }, inputStyle: { width: props.width ?? '10rem' }, actionTools: React.createElement(Box, { display: "flex", flexDirection: "row", alignItems: "center", flex: 'none' },
20
+ return (React.createElement(AdaptableFormControlTextClear, { "aria-label": 'Quick Search', type: "text", autoFocus: props.autoFocus, placeholder: adaptable.api.optionsApi.getQuickSearchOptions().quickSearchPlaceholder, className: join('ab-DashboardToolbar__QuickSearch__text', props.className), value: searchText, OnTextChange: search, style: { height: '100%' }, inputStyle: { width: props.width ?? '10rem' }, actionTools: isServerSideRowModel ? null : (React.createElement(Box, { display: "flex", flexDirection: "row", alignItems: "center", flex: 'none' },
20
21
  React.createElement(SimpleButton, { "aria-label": 'Previous Match', icon: "arrow-up", px: 0, py: 0, mr: 1, disabled: !searchText, variant: "text", onClick: () => adaptable.api.quickSearchApi.gotoPreviousMatch() }),
21
- React.createElement(SimpleButton, { "aria-label": 'Next Match', icon: "arrow-down", px: 0, py: 0, mr: 1, disabled: !searchText, variant: "text", onClick: () => adaptable.api.quickSearchApi.gotoNextMatch() })) }));
22
+ React.createElement(SimpleButton, { "aria-label": 'Next Match', icon: "arrow-down", px: 0, py: 0, mr: 1, disabled: !searchText, variant: "text", onClick: () => adaptable.api.quickSearchApi.gotoNextMatch() }))) }));
22
23
  };
@@ -1322,12 +1322,12 @@ You need to define at least one Layout!`);
1322
1322
  this.autoSizeLayoutIfNeeded();
1323
1323
  }));
1324
1324
  /**
1325
- * Use Case: A format column that has ColumnGroupState needs to be re-evaluated
1325
+ * Use Case: A format column that has ColumnGroupScope needs to be re-evaluated
1326
1326
  * whenever a column group is expanded or collapsed
1327
1327
  */
1328
1328
  this.agGridAdapter.getAgGridApi().addEventListener('columnGroupOpened', (this.listenerColumnGroupOpened = () => {
1329
1329
  if (this.api.formatColumnApi.getActiveFormatColumns().some((fc) => {
1330
- return fc.ColumnGroupState != null;
1330
+ return fc.ColumnGroupScope != null;
1331
1331
  })) {
1332
1332
  this.updateColumnModelAndRefreshGrid();
1333
1333
  }
@@ -36,6 +36,7 @@ export declare class AgGridColumnAdapter {
36
36
  private setupColumnValueSetter;
37
37
  private setupColumnComparator;
38
38
  private setupColumnGetFindText;
39
+ private getCellSearchText;
39
40
  private isCellSearchable;
40
41
  private isQuickSearchActive;
41
42
  private getEditableCellClass;
@@ -1,3 +1,4 @@
1
+ import kebabCase from 'lodash/kebabCase';
1
2
  import merge from 'lodash/merge';
2
3
  import { FilterWrapperFactory } from './FilterWrapper';
3
4
  import { FloatingFilterWrapperFactory } from './FloatingFilterWrapper';
@@ -210,15 +211,17 @@ export class AgGridColumnAdapter {
210
211
  const quickSearchCurrentTextMatchStyle = this.getQuickSearchCurrentTextMatchStyle();
211
212
  const textMatchStyle = quickSearchTextMatchStyle
212
213
  ? Object.entries(quickSearchTextMatchStyle).reduce((acc, [key, value]) => {
214
+ // needed as AG-Grid vanilla turns all CSS props
215
+ // to kebab, while AG Grid React does not
213
216
  // @ts-ignore
214
- acc[`--ab-dynamic-${key}`] = value;
217
+ acc[`--ab-dynamic-${kebabCase(key)}`] = value;
215
218
  return acc;
216
219
  }, {})
217
220
  : undefined;
218
221
  const currentTextMatchStyle = quickSearchCurrentTextMatchStyle
219
222
  ? Object.entries(quickSearchCurrentTextMatchStyle).reduce((acc, [key, value]) => {
220
223
  // @ts-ignore
221
- acc[`--ab-dynamic-${key}`] = value;
224
+ acc[`--ab-dynamic-${kebabCase(key)}`] = value;
222
225
  return acc;
223
226
  }, {})
224
227
  : undefined;
@@ -685,18 +688,25 @@ export class AgGridColumnAdapter {
685
688
  }
686
689
  const getCellSearchText = this.adaptableOptions.quickSearchOptions.getCellSearchText;
687
690
  if (getCellSearchText) {
688
- const quickSearchValue = this.adaptableApi.quickSearchApi.getQuickSearchValue();
689
- const quickSearchContext = {
690
- ...this.adaptableApi.internalApi.buildBaseContext(),
691
- gridCell,
692
- quickSearchValue,
693
- };
694
- return getCellSearchText(quickSearchContext);
691
+ return this.getCellSearchText(gridCell);
695
692
  }
696
693
  return userGetFindText?.(params) ?? gridCell.displayValue;
697
694
  };
698
695
  });
699
696
  }
697
+ getCellSearchText(gridCell) {
698
+ const getCellSearchText = this.adaptableOptions.quickSearchOptions.getCellSearchText;
699
+ if (getCellSearchText) {
700
+ const quickSearchValue = this.adaptableApi.quickSearchApi.getQuickSearchValue();
701
+ const quickSearchContext = {
702
+ ...this.adaptableApi.internalApi.buildBaseContext(),
703
+ gridCell,
704
+ quickSearchValue,
705
+ };
706
+ return getCellSearchText(quickSearchContext);
707
+ }
708
+ return gridCell.displayValue;
709
+ }
700
710
  isCellSearchable(gridCell) {
701
711
  const isCellSearchableFn = this.adaptableOptions.quickSearchOptions.isCellSearchable;
702
712
  if (!gridCell.column) {
@@ -732,6 +742,16 @@ export class AgGridColumnAdapter {
732
742
  if (!column) {
733
743
  return false;
734
744
  }
745
+ const isServerSideRowModel = this.adaptableApi.gridApi.getAgGridRowModelType() === 'serverSide';
746
+ if (isServerSideRowModel) {
747
+ const isCaseSensitive = this.adaptableOptions.quickSearchOptions.isQuickSearchCaseSensitive;
748
+ const cellDisplayValue = String(this.getCellSearchText(gridCell));
749
+ const displayValue = isCaseSensitive
750
+ ? cellDisplayValue
751
+ : cellDisplayValue.toLocaleLowerCase();
752
+ const searchText = isCaseSensitive ? quickSearchValue : quickSearchValue.toLocaleLowerCase();
753
+ return displayValue.indexOf(searchText) !== -1;
754
+ }
735
755
  return (this.agGridApi.findGetNumMatches({
736
756
  column,
737
757
  node: gridCell.rowNode,
@@ -180,19 +180,19 @@ export class AgGridExportAdapter {
180
180
  // recreating the standard AG Grid styling for row groups: 'Parent -> Child'
181
181
  // additionally the values are formatted
182
182
  let rowGroupNode = params.node;
183
- const isFooterRow = rowGroupNode.footer;
183
+ const agColumn = params.column;
184
184
  const rowGroupSummary = [
185
- this.processRowGroupForExcelExport(rowGroupNode, exportContext) ?? '',
185
+ this.processRowGroupForExcelExport(rowGroupNode, exportContext, agColumn) ?? '',
186
186
  ];
187
187
  while (rowGroupNode.parent) {
188
188
  rowGroupNode = rowGroupNode.parent;
189
- const formattedParentNode = this.processRowGroupForExcelExport(rowGroupNode, exportContext);
189
+ const formattedParentNode = this.processRowGroupForExcelExport(rowGroupNode, exportContext, agColumn);
190
190
  if (formattedParentNode) {
191
191
  rowGroupSummary.push(formattedParentNode);
192
192
  }
193
193
  }
194
194
  let summary = rowGroupSummary.reverse().join(' -> ');
195
- if (isFooterRow) {
195
+ if (agColumn?.getColId() === AG_GRID_GROUPED_COLUMN && rowGroupNode.footer) {
196
196
  summary = `Total: ${summary}`;
197
197
  }
198
198
  return summary;
@@ -407,17 +407,29 @@ export class AgGridExportAdapter {
407
407
  }
408
408
  return this.getCellExportValueFromRawValue(rowNode, this.adaptableApi.gridApi.getRawValueFromRowNode(rowNode, columnId), columnId, exportContext);
409
409
  }
410
- processRowGroupForExcelExport(rowNode, exportContext) {
410
+ processRowGroupForExcelExport(rowNode, exportContext, agColumn) {
411
411
  if (this.isTreeDataGrid()) {
412
412
  return rowNode.key;
413
413
  }
414
- const columnId = rowNode.field ??
415
- rowNode.rowGroupColumn?.getColId() ??
416
- rowNode.rowGroupColumn?.getColDef()?.field;
417
- if (!columnId || !rowNode.key) {
414
+ const getColIdAndRawValue = () => {
415
+ if (this.adaptableApi.columnApi.isAutoRowGroupColumn(agColumn?.getColId())) {
416
+ const columnId = rowNode.field ??
417
+ rowNode.rowGroupColumn?.getColId() ??
418
+ rowNode.rowGroupColumn?.getColDef()?.field;
419
+ let rawValue = rowNode.key;
420
+ return { columnId, rawValue };
421
+ }
422
+ if (this.adaptableApi.columnApi.isPivotResultColumn(agColumn.getColId())) {
423
+ const columnId = agColumn.getColId();
424
+ const rawValue = rowNode.aggData?.[columnId];
425
+ return { columnId, rawValue };
426
+ }
427
+ return {};
428
+ };
429
+ let { columnId, rawValue } = getColIdAndRawValue();
430
+ if (!columnId || rawValue == null) {
418
431
  return;
419
432
  }
420
- let rawValue = rowNode.key;
421
433
  const columnDataType = this.adaptableApi.columnApi.getColumnDataTypeForColumnId(columnId);
422
434
  if ((columnDataType === 'date' || columnDataType === 'dateString') &&
423
435
  typeof rawValue === 'string' &&
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: 1749810312509 || Date.now(),
4
- VERSION: "20.2.0" || '--current-version--',
3
+ PUBLISH_TIMESTAMP: 1750416425464 || Date.now(),
4
+ VERSION: "20.2.1" || '--current-version--',
5
5
  };