@adaptabletools/adaptable 24.0.0-canary.5 → 24.0.0-canary.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/devtools.d.ts +182 -1
- package/index.css +300 -275
- package/package.json +2 -1
- package/src/AdaptableInterfaces/IAdaptable.d.ts +4 -4
- package/src/AdaptableOptions/DefaultAdaptableOptions.js +5 -5
- package/src/AdaptableOptions/FlashingCellOptions.d.ts +3 -3
- package/src/AdaptableOptions/SettingsPanelOptions.d.ts +6 -4
- package/src/AdaptableOptions/StateOptions.d.ts +37 -13
- package/src/AdaptableOptions/UserInterfaceOptions.d.ts +4 -6
- package/src/AdaptableState/AdaptableState.d.ts +2 -0
- package/src/AdaptableState/QuickSearchState.d.ts +4 -0
- package/src/AdaptableState/StyledColumns/GradientStyle.d.ts +4 -0
- package/src/Api/Implementation/ColumnScopeApiImpl.js +3 -3
- package/src/Api/Implementation/QuickSearchApiImpl.js +2 -2
- package/src/Api/Implementation/StateApiImpl.d.ts +1 -1
- package/src/Api/Implementation/StateApiImpl.js +4 -3
- package/src/Api/Implementation/UserInterfaceApiImpl.d.ts +0 -1
- package/src/Api/Implementation/UserInterfaceApiImpl.js +9 -15
- package/src/Api/Internal/AdaptableInternalApi.js +5 -3
- package/src/Api/Internal/CalculatedColumnInternalApi.js +1 -1
- package/src/Api/Internal/StateInternalApi.d.ts +1 -1
- package/src/Api/Internal/StateInternalApi.js +6 -5
- package/src/Api/StateApi.d.ts +2 -2
- package/src/Api/UserInterfaceApi.d.ts +0 -4
- package/src/Redux/ActionsReducers/QuickSearchRedux.d.ts +9 -4
- package/src/Redux/ActionsReducers/QuickSearchRedux.js +12 -7
- package/src/Redux/Store/AdaptableReduxLocalStorageEngine.d.ts +8 -0
- package/src/Redux/Store/AdaptableReduxLocalStorageEngine.js +12 -12
- package/src/Redux/Store/AdaptableStore.d.ts +8 -5
- package/src/Redux/Store/AdaptableStore.js +51 -21
- package/src/Redux/Store/Interface/IAdaptableStore.d.ts +5 -5
- package/src/Redux/Store/Interface/IStorageEngine.d.ts +4 -4
- package/src/Redux/Store/StateOptionsGuards.d.ts +58 -0
- package/src/Redux/Store/StateOptionsGuards.js +112 -0
- package/src/Redux/Store/isTransientReduxAction.d.ts +5 -0
- package/src/Redux/Store/isTransientReduxAction.js +19 -0
- package/src/Utilities/Constants/DocumentationLinkConstants.d.ts +1 -0
- package/src/Utilities/Constants/DocumentationLinkConstants.js +1 -0
- package/src/Utilities/Constants/ReduxConstants.d.ts +2 -2
- package/src/Utilities/Constants/ReduxConstants.js +5 -5
- package/src/Utilities/Helpers/AlertTypeHelper.d.ts +1 -1
- package/src/Utilities/Helpers/SettingsPanelHelper.d.ts +14 -0
- package/src/Utilities/Helpers/SettingsPanelHelper.js +37 -1
- package/src/Utilities/Helpers/UIHelper.d.ts +12 -14
- package/src/Utilities/Helpers/UIHelper.js +12 -35
- package/src/Utilities/ObjectFactory.js +3 -3
- package/src/View/Components/Popups/AdaptablePopup/Navigation.js +9 -11
- package/src/View/Components/StyleComponent.js +2 -2
- package/src/View/Dashboard/Dashboard.d.ts +1 -1
- package/src/View/Dashboard/Dashboard.js +1 -1
- package/src/View/Dashboard/DashboardPopupSections.js +1 -1
- package/src/View/GridInfo/GridInfoPopup.js +62 -25
- package/src/View/QuickSearch/QuickSearchInput.js +1 -1
- package/src/View/QuickSearch/QuickSearchPopup.d.ts +1 -1
- package/src/View/QuickSearch/QuickSearchPopup.js +1 -1
- package/src/View/QuickSearch/Utilities/useQuickSearchDebounced.d.ts +2 -2
- package/src/View/StyledColumn/RangesComponent.js +13 -16
- package/src/View/StyledColumn/Wizard/BadgePillStyleEditor.d.ts +0 -2
- package/src/View/StyledColumn/Wizard/BadgePillStyleEditor.js +2 -2
- package/src/View/StyledColumn/Wizard/StyledColumnBadgeSection.js +2 -3
- package/src/View/StyledColumn/Wizard/StyledColumnSliceStyleEditors.d.ts +0 -3
- package/src/View/StyledColumn/Wizard/StyledColumnSliceStyleEditors.js +3 -3
- package/src/View/StyledColumn/Wizard/StyledColumnSparklineSettingsSection.js +7 -11
- package/src/View/StyledColumn/Wizard/StyledColumnWizardBulletSection.js +6 -6
- package/src/View/StyledColumn/Wizard/StyledColumnWizardGradientSection.js +2 -2
- package/src/View/StyledColumn/Wizard/StyledColumnWizardIconSection.js +2 -2
- package/src/View/StyledColumn/Wizard/StyledColumnWizardRangeBarSection.js +8 -8
- package/src/View/StyledColumn/Wizard/StyledColumnWizardRatingSection.js +4 -4
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/StyledColumnWizardRangesSection.js +2 -2
- package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/StyledColumnWizardStyleSection.js +4 -4
- package/src/View/Wizard/CollapsibleWizardCard.d.ts +3 -1
- package/src/View/Wizard/CollapsibleWizardCard.js +17 -9
- package/src/agGrid/AdaptableAgGrid.d.ts +4 -4
- package/src/agGrid/AdaptableAgGrid.js +2 -0
- package/src/agGrid/AgGridColumnAdapter.d.ts +1 -1
- package/src/agGrid/AgGridColumnAdapter.js +4 -4
- package/src/components/ColorField/index.d.ts +14 -0
- package/src/components/ColorField/index.js +6 -0
- package/src/components/aql/QueryBuilder/QueryBuilderInputs.js +1 -1
- package/src/env.js +2 -2
- package/src/layout-manager/src/normalizeLayoutModel.d.ts +1 -1
- package/src/layout-manager/src/simplifyLayoutModel.d.ts +1 -1
- package/src/migration/AdaptableUpgradeHelper.d.ts +7 -2
- package/src/migration/VersionUpgrade17.js +13 -8
- package/src/migration/VersionUpgrade24.d.ts +9 -0
- package/src/migration/VersionUpgrade24.js +27 -0
- package/src/setupDevTools.js +605 -112
- package/src/types.d.ts +1 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
- package/vendor/components/Button/index.d.ts +1 -1
- package/vendor/components/Button/index.d.ts.map +1 -1
- package/vendor/components/Button/index.js.map +1 -1
- package/vendor/components/CheckBox/index.d.ts +1 -1
- package/vendor/components/CheckBox/index.d.ts.map +1 -1
- package/vendor/components/CheckBox/index.js.map +1 -1
- package/vendor/components/ColorField/index.d.ts +43 -0
- package/vendor/components/ColorField/index.d.ts.map +1 -0
- package/vendor/components/ColorField/index.js +81 -0
- package/vendor/components/ColorField/index.js.map +1 -0
- package/vendor/components/ColorPicker/colorPickerTab.d.ts +4 -0
- package/vendor/components/ColorPicker/colorPickerTab.d.ts.map +1 -0
- package/vendor/components/ColorPicker/colorPickerTab.js +28 -0
- package/vendor/components/ColorPicker/colorPickerTab.js.map +1 -0
- package/vendor/components/ColorPicker/index.d.ts +59 -0
- package/vendor/components/ColorPicker/index.d.ts.map +1 -0
- package/vendor/components/ColorPicker/index.js +204 -0
- package/vendor/components/ColorPicker/index.js.map +1 -0
- package/vendor/components/ColorPicker/themeColors.d.ts +53 -0
- package/vendor/components/ColorPicker/themeColors.d.ts.map +1 -0
- package/vendor/components/ColorPicker/themeColors.js +110 -0
- package/vendor/components/ColorPicker/themeColors.js.map +1 -0
- package/vendor/components/Combobox/VirtualizedList.d.ts +1 -1
- package/vendor/components/Combobox/VirtualizedList.d.ts.map +1 -1
- package/vendor/components/Combobox/VirtualizedList.js.map +1 -1
- package/vendor/components/Combobox/index.d.ts +1 -1
- package/vendor/components/Combobox/index.d.ts.map +1 -1
- package/vendor/components/Combobox/index.js.map +1 -1
- package/vendor/components/NumberInput/index.d.ts +51 -0
- package/vendor/components/NumberInput/index.d.ts.map +1 -0
- package/vendor/components/NumberInput/index.js +82 -0
- package/vendor/components/NumberInput/index.js.map +1 -0
- package/vendor/components/index.css +280 -24
- package/vendor/components/index.d.ts +6 -0
- package/vendor/components/index.d.ts.map +1 -1
- package/vendor/components/index.js +3 -0
- package/vendor/components/index.js.map +1 -1
- package/vendor/components/ui/combobox.d.ts.map +1 -1
- package/vendor/components/ui/combobox.js +1 -1
- package/vendor/components/ui/combobox.js.map +1 -1
- package/vendor/components/ui/input-group.d.ts.map +1 -1
- package/vendor/components/ui/input-group.js +5 -4
- package/vendor/components/ui/input-group.js.map +1 -1
- package/src/components/ColorPicker/ColorPicker.d.ts +0 -12
- package/src/components/ColorPicker/ColorPicker.js +0 -48
- package/src/components/ColorPicker/OptionalColorPicker.d.ts +0 -12
- package/src/components/ColorPicker/OptionalColorPicker.js +0 -13
- package/src/components/ColorPicker/index.d.ts +0 -2
- package/src/components/ColorPicker/index.js +0 -2
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import IStorageEngine from './Interface/IStorageEngine';
|
|
2
2
|
import { InitialState } from '../../AdaptableState/InitialState';
|
|
3
3
|
import { AdaptableLoadStateFunction, AdaptablePersistStateFunction } from '../../AdaptableOptions/StateOptions';
|
|
4
|
+
/**
|
|
5
|
+
* Default `persistState` implementation - writes the state to localStorage under `adaptableStateKey`
|
|
6
|
+
*/
|
|
7
|
+
export declare const persistState: AdaptablePersistStateFunction;
|
|
8
|
+
/**
|
|
9
|
+
* Default `loadState` implementation - reads the state from localStorage under `adaptableStateKey`
|
|
10
|
+
*/
|
|
11
|
+
export declare const loadState: AdaptableLoadStateFunction;
|
|
4
12
|
export declare function createEngine(config: {
|
|
5
13
|
adaptableId: string;
|
|
6
14
|
adaptableStateKey: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { debounce } from '../../Utilities/Helpers/TimingHelper';
|
|
2
2
|
import { MergeStateFunction } from './AdaptableReduxMerger';
|
|
3
3
|
import { AdaptableLogger } from '../../agGrid/AdaptableLogger';
|
|
4
|
+
import { runAsyncStateFunction, runSyncStateFunction } from './StateOptionsGuards';
|
|
4
5
|
const checkStatus = (response) => {
|
|
5
6
|
const error = new Error(response.statusText);
|
|
6
7
|
if (response.status >= 200 && response.status < 300) {
|
|
@@ -8,7 +9,7 @@ const checkStatus = (response) => {
|
|
|
8
9
|
}
|
|
9
10
|
throw error;
|
|
10
11
|
};
|
|
11
|
-
const persistState = (state, config) => {
|
|
12
|
+
export const persistState = (state, config) => {
|
|
12
13
|
return new Promise((resolve, reject) => {
|
|
13
14
|
try {
|
|
14
15
|
localStorage.setItem(config.adaptableStateKey, JSON.stringify(state));
|
|
@@ -19,7 +20,7 @@ const persistState = (state, config) => {
|
|
|
19
20
|
}
|
|
20
21
|
});
|
|
21
22
|
};
|
|
22
|
-
const loadState = ({
|
|
23
|
+
export const loadState = ({ adaptableStateKey }) => {
|
|
23
24
|
const jsonState = localStorage.getItem(adaptableStateKey);
|
|
24
25
|
const parsedJsonState = JSON.parse(jsonState) || {};
|
|
25
26
|
return Promise.resolve(parsedJsonState);
|
|
@@ -49,7 +50,7 @@ class AdaptableReduxLocalStorageEngine {
|
|
|
49
50
|
this.adaptableStateKey = adaptableStateKey;
|
|
50
51
|
}
|
|
51
52
|
load(adaptableInstance, initialState = this.initialState) {
|
|
52
|
-
return (this.loadState || loadState
|
|
53
|
+
return runAsyncStateFunction('loadState', this.loadState || loadState, [adaptableInstance.api.stateApi.internalApi.buildAdaptableStateFunctionConfig()], adaptableInstance.logger).then((parsedJsonState) => {
|
|
53
54
|
return Promise.resolve(initialState)
|
|
54
55
|
.then((parsedInitialState) => {
|
|
55
56
|
return MergeStateFunction(parsedInitialState, parsedJsonState);
|
|
@@ -67,20 +68,19 @@ class AdaptableReduxLocalStorageEngine {
|
|
|
67
68
|
const config = adaptableInstance.api.stateApi.internalApi.buildAdaptableStateFunctionConfig();
|
|
68
69
|
config.actionName = actionName;
|
|
69
70
|
config.previousState = adaptableInstance.adaptableStore.getPreviousStorageState() || null;
|
|
70
|
-
let stateObject
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
stateObject = getTransformedState(stateObject, config);
|
|
71
|
+
let stateObject;
|
|
72
|
+
try {
|
|
73
|
+
stateObject = runSyncStateFunction('saveState', adaptableInstance.adaptableOptions.stateOptions.saveState, structuredClone(state), config, adaptableInstance.logger);
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
catch (error) {
|
|
76
|
+
adaptableInstance.logger.consoleError('Adaptable State was NOT persisted:', error instanceof Error ? error.message : error);
|
|
77
|
+
return Promise.reject(error);
|
|
78
78
|
}
|
|
79
|
-
return
|
|
79
|
+
return runAsyncStateFunction('persistState', this.persistState || persistState, [stateObject, config], adaptableInstance.logger).catch(rejectWithMessage);
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
function rejectWithMessage(error) {
|
|
83
|
-
return Promise.reject(error
|
|
83
|
+
return Promise.reject(error?.message ?? error);
|
|
84
84
|
}
|
|
85
85
|
export function createEngine(config) {
|
|
86
86
|
return new AdaptableReduxLocalStorageEngine(config);
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import * as Redux from 'redux';
|
|
2
2
|
import { IAdaptable } from '../../AdaptableInterfaces/IAdaptable';
|
|
3
|
-
import { AdaptableState } from '../../AdaptableState/AdaptableState';
|
|
3
|
+
import { AdaptablePersistentState, AdaptableState } from '../../AdaptableState/AdaptableState';
|
|
4
4
|
import { BaseState } from '../../AdaptableState/BaseState';
|
|
5
5
|
import { IAdaptableStore, LoadStoreConfig } from './Interface/IAdaptableStore';
|
|
6
6
|
type EmitterCallback = (data?: any) => any;
|
|
7
7
|
type EmitterAnyCallback = (eventName: string, data?: any) => any;
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* Strips the transient (non-persisted) sections from the given state object - mutates and returns the same object.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getPersistableState: (state: AdaptableState) => AdaptablePersistentState;
|
|
9
12
|
export interface ResetUserDataAction extends Redux.Action {
|
|
10
13
|
}
|
|
11
14
|
export interface InitStateAction extends Redux.Action {
|
|
@@ -40,9 +43,9 @@ export declare class AdaptableStore implements IAdaptableStore {
|
|
|
40
43
|
*/
|
|
41
44
|
constructor(adaptable: IAdaptable);
|
|
42
45
|
destroy(): void;
|
|
43
|
-
getCurrentStorageState():
|
|
44
|
-
getPreviousStorageState():
|
|
45
|
-
saveStateNow(adaptable: IAdaptable, state?:
|
|
46
|
+
getCurrentStorageState(): AdaptablePersistentState;
|
|
47
|
+
getPreviousStorageState(): AdaptablePersistentState;
|
|
48
|
+
saveStateNow(adaptable: IAdaptable, state?: AdaptablePersistentState): Promise<any>;
|
|
46
49
|
loadStore: (config: LoadStoreConfig) => Promise<any>;
|
|
47
50
|
}
|
|
48
51
|
export {};
|
|
@@ -4,6 +4,7 @@ import * as PopupRedux from '../ActionsReducers/PopupRedux';
|
|
|
4
4
|
import { PROGRESS_INDICATOR_HIDE, PROGRESS_INDICATOR_SHOW } from '../ActionsReducers/PopupRedux';
|
|
5
5
|
import { createEngine as createEngineLocal } from './AdaptableReduxLocalStorageEngine';
|
|
6
6
|
import { mergeReducer } from './AdaptableReduxMerger';
|
|
7
|
+
import { runSyncStateFunction } from './StateOptionsGuards';
|
|
7
8
|
import { isRowChangeAlertDefinition } from '../../AdaptableState/AlertState';
|
|
8
9
|
import { getAlertCellDataChangedInfos, isAdaptableRowChangedAlert, } from '../../AdaptableState/Common/AdaptableAlert';
|
|
9
10
|
import { closeAgChartDefinitionIfOpen, closeExternalChartDefinitionIfOpen, } from '../../Utilities/Helpers/ChartHelper';
|
|
@@ -185,13 +186,9 @@ export class AdaptableStore {
|
|
|
185
186
|
!init &&
|
|
186
187
|
!this.loadStorageInProgress;
|
|
187
188
|
if (shouldPersist) {
|
|
188
|
-
|
|
189
|
-
storageState = getPersistableState(storageState);
|
|
189
|
+
const storageState = getPersistableState({ ...finalState });
|
|
190
190
|
this.currentStorageState = storageState;
|
|
191
|
-
this.previousStorageState = { ...state };
|
|
192
|
-
NON_PERSISTENT_STORE_KEYS.forEach((key) => {
|
|
193
|
-
delete this.previousStorageState[key];
|
|
194
|
-
});
|
|
191
|
+
this.previousStorageState = getPersistableState({ ...state });
|
|
195
192
|
storageEngine.save(adaptable, storageState, action.type);
|
|
196
193
|
}
|
|
197
194
|
return finalState;
|
|
@@ -245,7 +242,9 @@ export class AdaptableStore {
|
|
|
245
242
|
return this.previousStorageState;
|
|
246
243
|
}
|
|
247
244
|
saveStateNow(adaptable, state) {
|
|
248
|
-
const newState = state
|
|
245
|
+
const newState = state
|
|
246
|
+
? getPersistableState({ ...state })
|
|
247
|
+
: this.getCurrentStorageState();
|
|
249
248
|
if (newState) {
|
|
250
249
|
return this.storageEngine.saveNow(adaptable, newState, 'API_CALL_SAVE_STATE');
|
|
251
250
|
}
|
|
@@ -260,7 +259,8 @@ export class AdaptableStore {
|
|
|
260
259
|
.load(adaptable, initialState ?? adaptable.adaptableOptions.initialState)
|
|
261
260
|
.then((storedState) => {
|
|
262
261
|
if (storedState && this.loadStateOnStartup) {
|
|
263
|
-
|
|
262
|
+
const appliedState = runSyncStateFunction('applyState', adaptable.adaptableOptions.stateOptions.applyState, storedState, adaptable.api.stateApi.internalApi.buildAdaptableStateFunctionConfig(), adaptable.logger);
|
|
263
|
+
this.TheStore.dispatch(LoadState(postProcessState(appliedState)));
|
|
264
264
|
}
|
|
265
265
|
})
|
|
266
266
|
.then(() => {
|
|
@@ -402,10 +402,26 @@ function refreshFormulaTraceCells(adaptable, formulaTraceInfo) {
|
|
|
402
402
|
});
|
|
403
403
|
}
|
|
404
404
|
const LAYOUT_EXTENSION_OBJECT_ACTIONS = {
|
|
405
|
-
[AlertRedux.ALERT_DEFINITION_EDIT]: {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
405
|
+
[AlertRedux.ALERT_DEFINITION_EDIT]: {
|
|
406
|
+
module: 'Alert',
|
|
407
|
+
payloadKey: 'alertDefinition',
|
|
408
|
+
kind: 'edit',
|
|
409
|
+
},
|
|
410
|
+
[AlertRedux.ALERT_DEFINITION_DELETE]: {
|
|
411
|
+
module: 'Alert',
|
|
412
|
+
payloadKey: 'alertDefinition',
|
|
413
|
+
kind: 'delete',
|
|
414
|
+
},
|
|
415
|
+
[CustomSortRedux.CUSTOM_SORT_EDIT]: {
|
|
416
|
+
module: 'CustomSort',
|
|
417
|
+
payloadKey: 'customSort',
|
|
418
|
+
kind: 'edit',
|
|
419
|
+
},
|
|
420
|
+
[CustomSortRedux.CUSTOM_SORT_DELETE]: {
|
|
421
|
+
module: 'CustomSort',
|
|
422
|
+
payloadKey: 'customSort',
|
|
423
|
+
kind: 'delete',
|
|
424
|
+
},
|
|
409
425
|
[FlashingCellRedux.FLASHING_CELL_DEFINITION_EDIT]: {
|
|
410
426
|
module: 'FlashingCell',
|
|
411
427
|
payloadKey: 'flashingCellDefinition',
|
|
@@ -416,13 +432,21 @@ const LAYOUT_EXTENSION_OBJECT_ACTIONS = {
|
|
|
416
432
|
payloadKey: 'flashingCellDefinition',
|
|
417
433
|
kind: 'delete',
|
|
418
434
|
},
|
|
419
|
-
[FormatColumnRedux.FORMAT_COLUMN_EDIT]: {
|
|
435
|
+
[FormatColumnRedux.FORMAT_COLUMN_EDIT]: {
|
|
436
|
+
module: 'FormatColumn',
|
|
437
|
+
payloadKey: 'formatColumn',
|
|
438
|
+
kind: 'edit',
|
|
439
|
+
},
|
|
420
440
|
[FormatColumnRedux.FORMAT_COLUMN_DELETE]: {
|
|
421
441
|
module: 'FormatColumn',
|
|
422
442
|
payloadKey: 'formatColumn',
|
|
423
443
|
kind: 'delete',
|
|
424
444
|
},
|
|
425
|
-
[PlusMinusRedux.PLUS_MINUS_RULE_EDIT]: {
|
|
445
|
+
[PlusMinusRedux.PLUS_MINUS_RULE_EDIT]: {
|
|
446
|
+
module: 'PlusMinus',
|
|
447
|
+
payloadKey: 'plusMinusNudge',
|
|
448
|
+
kind: 'edit',
|
|
449
|
+
},
|
|
426
450
|
[PlusMinusRedux.PLUS_MINUS_RULE_DELETE]: {
|
|
427
451
|
module: 'PlusMinus',
|
|
428
452
|
payloadKey: 'plusMinusNudge',
|
|
@@ -430,7 +454,11 @@ const LAYOUT_EXTENSION_OBJECT_ACTIONS = {
|
|
|
430
454
|
},
|
|
431
455
|
[ShortcutRedux.SHORTCUT_EDIT]: { module: 'Shortcut', payloadKey: 'shortcut', kind: 'edit' },
|
|
432
456
|
[ShortcutRedux.SHORTCUT_DELETE]: { module: 'Shortcut', payloadKey: 'shortcut', kind: 'delete' },
|
|
433
|
-
[StyledColumnRedux.STYLED_COLUMN_EDIT]: {
|
|
457
|
+
[StyledColumnRedux.STYLED_COLUMN_EDIT]: {
|
|
458
|
+
module: 'StyledColumn',
|
|
459
|
+
payloadKey: 'StyledColumn',
|
|
460
|
+
kind: 'edit',
|
|
461
|
+
},
|
|
434
462
|
[StyledColumnRedux.STYLED_COLUMN_DELETE]: {
|
|
435
463
|
module: 'StyledColumn',
|
|
436
464
|
payloadKey: 'StyledColumn',
|
|
@@ -585,8 +613,8 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
585
613
|
if (!adaptable.api.freeTextColumnApi.internalApi.validateDeletedFreeTextColumn(actionTyped.freeTextColumn)) {
|
|
586
614
|
return;
|
|
587
615
|
}
|
|
588
|
-
if (adaptable.api.optionsApi.getLayoutOptions()
|
|
589
|
-
|
|
616
|
+
if (adaptable.api.optionsApi.getLayoutOptions()?.autoRemoveDeletedColumnsFromLayouts !==
|
|
617
|
+
false) {
|
|
590
618
|
adaptable.api.layoutApi.internalApi.removeColumnIdFromAllLayouts(actionTyped.freeTextColumn.ColumnId);
|
|
591
619
|
}
|
|
592
620
|
}
|
|
@@ -607,8 +635,8 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
607
635
|
if (!adaptable.api.calculatedColumnApi.internalApi.validateDeletedCalculatedColumn(calculatedColumn)) {
|
|
608
636
|
return;
|
|
609
637
|
}
|
|
610
|
-
if (adaptable.api.optionsApi.getLayoutOptions()
|
|
611
|
-
|
|
638
|
+
if (adaptable.api.optionsApi.getLayoutOptions()?.autoRemoveDeletedColumnsFromLayouts !==
|
|
639
|
+
false) {
|
|
612
640
|
adaptable.api.layoutApi.internalApi.removeColumnIdFromAllLayouts(calculatedColumn.ColumnId);
|
|
613
641
|
}
|
|
614
642
|
}
|
|
@@ -692,10 +720,12 @@ const adaptableMiddleware = (adaptable) => (function(middlewareAPI) {
|
|
|
692
720
|
adaptable.refreshSortIfColumnsSorted();
|
|
693
721
|
return returnAction;
|
|
694
722
|
}
|
|
723
|
+
case QuickSearchRedux.QUICK_SEARCH_CLEAR:
|
|
695
724
|
case QuickSearchRedux.QUICK_SEARCH_RUN: {
|
|
696
725
|
let returnAction = next(action);
|
|
697
|
-
const
|
|
698
|
-
|
|
726
|
+
const searchText = action.type === QuickSearchRedux.QUICK_SEARCH_CLEAR
|
|
727
|
+
? ''
|
|
728
|
+
: action.quickSearchText;
|
|
699
729
|
adaptable.setAgGridFindSearchValue(searchText);
|
|
700
730
|
adaptable.api.gridApi.refreshAllCells(true);
|
|
701
731
|
if (adaptable.adaptableOptions.quickSearchOptions.filterGridAfterQuickSearch) {
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import * as Redux from 'redux';
|
|
2
|
-
import { AdaptableState } from '../../../AdaptableState/AdaptableState';
|
|
2
|
+
import { AdaptablePersistentState, AdaptableState } from '../../../AdaptableState/AdaptableState';
|
|
3
3
|
import { InitialState } from '../../../types';
|
|
4
4
|
import { IAdaptable } from '../../../AdaptableInterfaces/IAdaptable';
|
|
5
5
|
export interface LoadStoreConfig {
|
|
6
6
|
adaptable: IAdaptable;
|
|
7
7
|
adaptableStateKey: string;
|
|
8
8
|
initialState?: InitialState;
|
|
9
|
-
postLoadHook?: (state:
|
|
9
|
+
postLoadHook?: (state: Partial<AdaptablePersistentState>) => Partial<AdaptablePersistentState>;
|
|
10
10
|
}
|
|
11
11
|
export interface IAdaptableStore {
|
|
12
12
|
TheStore: Redux.Store<AdaptableState>;
|
|
13
13
|
Load: Promise<any>;
|
|
14
14
|
loadStore: (config: LoadStoreConfig) => Promise<any>;
|
|
15
|
-
getCurrentStorageState: () =>
|
|
16
|
-
getPreviousStorageState: () =>
|
|
17
|
-
saveStateNow: (adaptable: IAdaptable, state?:
|
|
15
|
+
getCurrentStorageState: () => AdaptablePersistentState | void;
|
|
16
|
+
getPreviousStorageState: () => AdaptablePersistentState | void;
|
|
17
|
+
saveStateNow: (adaptable: IAdaptable, state?: AdaptablePersistentState) => Promise<any>;
|
|
18
18
|
on: (eventName: string, callback: (data?: any) => any) => () => void;
|
|
19
19
|
onAny: (callback: (eventName: string, data?: any) => any) => () => void;
|
|
20
20
|
onBeforeAny: (callback: (eventName: string, data?: any) => any) => () => void;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AdaptablePersistentState } from '../../../AdaptableState/AdaptableState';
|
|
2
2
|
import { InitialState } from '../../../AdaptableState/InitialState';
|
|
3
3
|
import { IAdaptable } from '../../../AdaptableInterfaces/IAdaptable';
|
|
4
4
|
export default interface IStorageEngine {
|
|
5
|
-
load(adaptable: IAdaptable, initialState?: string | InitialState): Promise<
|
|
6
|
-
save(adaptable: IAdaptable, state:
|
|
7
|
-
saveNow(adaptable: IAdaptable, state:
|
|
5
|
+
load(adaptable: IAdaptable, initialState?: string | InitialState): Promise<Partial<AdaptablePersistentState> | void>;
|
|
6
|
+
save(adaptable: IAdaptable, state: AdaptablePersistentState, actionName: string): Promise<any>;
|
|
7
|
+
saveNow(adaptable: IAdaptable, state: AdaptablePersistentState, actionName: string): Promise<any>;
|
|
8
8
|
setStateKey(stateKey: string): void;
|
|
9
9
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AdaptablePersistentState } from '../../AdaptableState/AdaptableState';
|
|
2
|
+
import { AdaptableStateFunctionConfig, StateOptions } from '../../AdaptableOptions/StateOptions';
|
|
3
|
+
/**
|
|
4
|
+
* Runtime guards for the `StateOptions` functions.
|
|
5
|
+
*
|
|
6
|
+
* The most frequent mistakes when implementing these functions are:
|
|
7
|
+
* - providing an `async` function (or otherwise returning a Promise) for `saveState` / `applyState`, which are synchronous
|
|
8
|
+
* - mutating the state in `saveState` / `applyState` but forgetting to return it
|
|
9
|
+
* - returning a plain value (not a Promise) from `loadState` / `persistState`
|
|
10
|
+
*
|
|
11
|
+
* The helpers below detect these cases - as early as possible - and either recover (when there is only one sensible
|
|
12
|
+
* interpretation) or fail with an actionable error message instead of an obscure one further down the line.
|
|
13
|
+
*/
|
|
14
|
+
export type StateOptionsLogger = {
|
|
15
|
+
consoleError(message: string, ...optionalParams: any[]): void;
|
|
16
|
+
consoleWarn(message: string, ...optionalParams: any[]): void;
|
|
17
|
+
};
|
|
18
|
+
export type SyncStateFunctionName = 'saveState' | 'applyState';
|
|
19
|
+
export type AsyncStateFunctionName = 'loadState' | 'persistState' | 'clearState';
|
|
20
|
+
export type StateFunctionName = SyncStateFunctionName | AsyncStateFunctionName;
|
|
21
|
+
/**
|
|
22
|
+
* Error thrown when a `StateOptions` function breaks its contract
|
|
23
|
+
*/
|
|
24
|
+
export declare class AdaptableStateOptionsError extends Error {
|
|
25
|
+
constructor(message: string);
|
|
26
|
+
}
|
|
27
|
+
export declare const isThenable: (value: unknown) => value is PromiseLike<unknown>;
|
|
28
|
+
/**
|
|
29
|
+
* Detects functions declared with the `async` keyword (not transpiled to generators / promises)
|
|
30
|
+
*/
|
|
31
|
+
export declare const isAsyncFunction: (fn: unknown) => boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Validates the shape of `stateOptions` once, at initialisation - before any state is loaded or persisted.
|
|
34
|
+
*
|
|
35
|
+
* Reports (does not throw):
|
|
36
|
+
* - non-function values for any state function
|
|
37
|
+
* - `async` functions for `saveState` / `applyState`
|
|
38
|
+
* - `loadState` without `persistState` (or vice versa) - the localStorage fallback is used for the missing one,
|
|
39
|
+
* which makes the remote and local copies of the state diverge
|
|
40
|
+
*/
|
|
41
|
+
export declare function validateStateOptions(stateOptions: StateOptions | undefined, logger: StateOptionsLogger): void;
|
|
42
|
+
/**
|
|
43
|
+
* Invokes a synchronous state transform (`saveState` / `applyState`) and validates its result.
|
|
44
|
+
*
|
|
45
|
+
* - returns the result when it is a state object
|
|
46
|
+
* - **recovers** when the function returned nothing: the input state is used (the function most likely mutated it in place
|
|
47
|
+
* and forgot to `return` it) and an error is logged
|
|
48
|
+
* - **throws** `AdaptableStateOptionsError` when the result is a Promise (async function) or any other non-object value;
|
|
49
|
+
* there is no safe way to continue in these cases
|
|
50
|
+
*/
|
|
51
|
+
export declare function runSyncStateFunction<T extends Partial<AdaptablePersistentState>>(functionName: SyncStateFunctionName, fn: ((state: T, config: AdaptableStateFunctionConfig) => T) | undefined, state: T, config: AdaptableStateFunctionConfig, logger: StateOptionsLogger): T;
|
|
52
|
+
/**
|
|
53
|
+
* Invokes an asynchronous state function (`loadState` / `persistState` / `clearState`) and normalises its result to a Promise.
|
|
54
|
+
*
|
|
55
|
+
* A non-Promise result is logged (these functions are expected to be async) and wrapped in a resolved Promise, so a
|
|
56
|
+
* synchronous implementation degrades gracefully instead of failing with `.then is not a function`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function runAsyncStateFunction<TResult, TArgs extends unknown[]>(functionName: AsyncStateFunctionName, fn: (...args: TArgs) => Promise<TResult>, args: TArgs, logger: StateOptionsLogger): Promise<TResult>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { StatePersistenceDocsLink } from '../../Utilities/Constants/DocumentationLinkConstants';
|
|
2
|
+
const STATE_FUNCTION_NAMES = [
|
|
3
|
+
'loadState',
|
|
4
|
+
'persistState',
|
|
5
|
+
'applyState',
|
|
6
|
+
'saveState',
|
|
7
|
+
'clearState',
|
|
8
|
+
];
|
|
9
|
+
export class AdaptableStateOptionsError extends Error {
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.name = 'AdaptableStateOptionsError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export const isThenable = (value) => {
|
|
16
|
+
return value != null && typeof value.then === 'function';
|
|
17
|
+
};
|
|
18
|
+
export const isAsyncFunction = (fn) => {
|
|
19
|
+
return typeof fn === 'function' && fn.constructor?.name === 'AsyncFunction';
|
|
20
|
+
};
|
|
21
|
+
const isStateObject = (value) => {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
23
|
+
};
|
|
24
|
+
const docs = `See ${StatePersistenceDocsLink}`;
|
|
25
|
+
const syncFunctionMustReturnMessage = (functionName) => `stateOptions.${functionName} must be synchronous and return the (modified) state object.`;
|
|
26
|
+
const asyncFunctionMessage = (functionName, reason) => `${syncFunctionMustReturnMessage(functionName)} ${reason} ` +
|
|
27
|
+
`Asynchronous work belongs in stateOptions.${functionName === 'saveState' ? 'persistState' : 'loadState'}. ${docs}`;
|
|
28
|
+
export function validateStateOptions(stateOptions, logger) {
|
|
29
|
+
if (!stateOptions) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
for (const functionName of STATE_FUNCTION_NAMES) {
|
|
33
|
+
const fn = stateOptions[functionName];
|
|
34
|
+
if (fn != null && typeof fn !== 'function') {
|
|
35
|
+
logger.consoleError(`stateOptions.${functionName} must be a function, but received ${describe(fn)}. ${docs}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
for (const functionName of ['saveState', 'applyState']) {
|
|
39
|
+
if (isAsyncFunction(stateOptions[functionName])) {
|
|
40
|
+
logger.consoleError(asyncFunctionMessage(functionName, 'It is declared as an async function.'));
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
const hasLoadState = typeof stateOptions.loadState === 'function';
|
|
44
|
+
const hasPersistState = typeof stateOptions.persistState === 'function';
|
|
45
|
+
if (hasLoadState !== hasPersistState) {
|
|
46
|
+
const provided = hasLoadState ? 'loadState' : 'persistState';
|
|
47
|
+
const missing = hasLoadState ? 'persistState' : 'loadState';
|
|
48
|
+
logger.consoleWarn(`stateOptions.${provided} is provided without stateOptions.${missing}; ` +
|
|
49
|
+
`the default localStorage implementation is used for ${missing}, so the loaded and the persisted state may diverge. ` +
|
|
50
|
+
`Provide both functions (or neither). ${docs}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
export function runSyncStateFunction(functionName, fn, state, config, logger) {
|
|
54
|
+
if (fn == null) {
|
|
55
|
+
return state;
|
|
56
|
+
}
|
|
57
|
+
if (typeof fn !== 'function') {
|
|
58
|
+
throw new AdaptableStateOptionsError(`stateOptions.${functionName} must be a function, but received ${describe(fn)}. ${docs}`);
|
|
59
|
+
}
|
|
60
|
+
const result = fn(state, config);
|
|
61
|
+
if (result === undefined) {
|
|
62
|
+
logger.consoleError(`${syncFunctionMustReturnMessage(functionName)} It returned nothing - ` +
|
|
63
|
+
`the state object passed to it is used instead (add 'return state;' to fix this). ${docs}`);
|
|
64
|
+
return state;
|
|
65
|
+
}
|
|
66
|
+
if (isThenable(result)) {
|
|
67
|
+
throw new AdaptableStateOptionsError(asyncFunctionMessage(functionName, 'It returned a Promise (is it an async function?).'));
|
|
68
|
+
}
|
|
69
|
+
if (!isStateObject(result)) {
|
|
70
|
+
throw new AdaptableStateOptionsError(`${syncFunctionMustReturnMessage(functionName)} It returned ${describe(result)}. ${docs}`);
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
export function runAsyncStateFunction(functionName, fn, args, logger) {
|
|
75
|
+
if (typeof fn !== 'function') {
|
|
76
|
+
return Promise.reject(new AdaptableStateOptionsError(`stateOptions.${functionName} must be a function, but received ${describe(fn)}. ${docs}`));
|
|
77
|
+
}
|
|
78
|
+
let result;
|
|
79
|
+
try {
|
|
80
|
+
result = fn(...args);
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
return Promise.reject(error);
|
|
84
|
+
}
|
|
85
|
+
if (!isThenable(result)) {
|
|
86
|
+
logger.consoleWarn(`stateOptions.${functionName} should be asynchronous and return a Promise, but it returned ${describe(result)}. The value is used as if it had been resolved. ${docs}`);
|
|
87
|
+
return Promise.resolve(result);
|
|
88
|
+
}
|
|
89
|
+
return Promise.resolve(result);
|
|
90
|
+
}
|
|
91
|
+
function describe(value) {
|
|
92
|
+
if (value === null) {
|
|
93
|
+
return 'null';
|
|
94
|
+
}
|
|
95
|
+
if (value === undefined) {
|
|
96
|
+
return 'undefined';
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
return 'an array';
|
|
100
|
+
}
|
|
101
|
+
if (isThenable(value)) {
|
|
102
|
+
return 'a Promise';
|
|
103
|
+
}
|
|
104
|
+
const type = typeof value;
|
|
105
|
+
if (type === 'object') {
|
|
106
|
+
return 'an object';
|
|
107
|
+
}
|
|
108
|
+
if (type === 'string') {
|
|
109
|
+
return `a string ('${String(value).slice(0, 40)}${String(value).length > 40 ? '…' : ''}')`;
|
|
110
|
+
}
|
|
111
|
+
return `${type} (${String(value)})`;
|
|
112
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as CommentsRedux from '../ActionsReducers/CommentsRedux';
|
|
2
|
+
import * as InternalRedux from '../ActionsReducers/InternalRedux';
|
|
3
|
+
import * as PluginsRedux from '../ActionsReducers/PluginsRedux';
|
|
4
|
+
import * as PopupRedux from '../ActionsReducers/PopupRedux';
|
|
5
|
+
const collectActionTypes = (reduxModule) => {
|
|
6
|
+
return Object.values(reduxModule).filter((value) => typeof value === 'string');
|
|
7
|
+
};
|
|
8
|
+
const TRANSIENT_REDUX_ACTION_TYPES = new Set([
|
|
9
|
+
...collectActionTypes(InternalRedux),
|
|
10
|
+
...collectActionTypes(PopupRedux),
|
|
11
|
+
...collectActionTypes(PluginsRedux),
|
|
12
|
+
...collectActionTypes(CommentsRedux),
|
|
13
|
+
]);
|
|
14
|
+
export function isTransientReduxAction(actionType) {
|
|
15
|
+
if (!actionType) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return TRANSIENT_REDUX_ACTION_TYPES.has(actionType);
|
|
19
|
+
}
|
|
@@ -16,3 +16,4 @@ export declare const AgGridModulesDocsLink = "https://www.adaptabletools.com/doc
|
|
|
16
16
|
export declare const AlertMessageDocsLink = "https://www.adaptabletools.com/docs/handbook-alerting-message";
|
|
17
17
|
export declare const FormatColumnPlaceholderDocsLink = "https://www.adaptabletools.com/docs/handbook-column-formatting-display-format-template";
|
|
18
18
|
export declare const AgGridRequiredModulesDocsLink = "https://www.adaptabletools.com/docs/getting-started-aggrid-modules#mandatory-modules";
|
|
19
|
+
export declare const StatePersistenceDocsLink = "https://www.adaptabletools.com/docs/dev-guide-adaptable-state-persistence";
|
|
@@ -16,3 +16,4 @@ export const AgGridModulesDocsLink = `${HOST_URL_DOCS}/getting-started-aggrid-mo
|
|
|
16
16
|
export const AlertMessageDocsLink = `${HOST_URL_DOCS}/handbook-alerting-message`;
|
|
17
17
|
export const FormatColumnPlaceholderDocsLink = `${HOST_URL_DOCS}/handbook-column-formatting-display-format-template`;
|
|
18
18
|
export const AgGridRequiredModulesDocsLink = `${HOST_URL_DOCS}/getting-started-aggrid-modules#mandatory-modules`;
|
|
19
|
+
export const StatePersistenceDocsLink = `${HOST_URL_DOCS}/dev-guide-adaptable-state-persistence`;
|
|
@@ -2,8 +2,8 @@ import { SummaryOperation } from '../../AdaptableState/Common/Enums';
|
|
|
2
2
|
import { SystemThemeEntry } from '../../AdaptableState/ThemeState';
|
|
3
3
|
export declare const CELL_SUMMARY_DEFAULT_OPERATION: SummaryOperation | string;
|
|
4
4
|
export declare const QUICK_SEARCH_DEFAULT_TEXT_BACK_COLOR: string;
|
|
5
|
-
export declare const
|
|
6
|
-
export declare const QUICK_SEARCH_DEFAULT_FORE_COLOR: string;
|
|
5
|
+
export declare const QUICK_SEARCH_DEFAULT_TEXT_FORE_COLOR: string;
|
|
7
6
|
export declare const QUICK_SEARCH_DEFAULT_CURRENT_BACK_COLOR: string;
|
|
7
|
+
export declare const QUICK_SEARCH_DEFAULT_CURRENT_FORE_COLOR: string;
|
|
8
8
|
export declare const SYSTEM_THEMES: SystemThemeEntry[];
|
|
9
9
|
export declare const THEME_DEFAULT_CURRENT_THEME: string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { SummaryOperation } from '../../AdaptableState/Common/Enums';
|
|
2
|
-
import {
|
|
2
|
+
import { themeColorVar } from '../../Utilities/Helpers/UIHelper';
|
|
3
3
|
import { LIGHT_THEME, DARK_THEME, OS_THEME } from './GeneralConstants';
|
|
4
4
|
export const CELL_SUMMARY_DEFAULT_OPERATION = SummaryOperation.Sum;
|
|
5
|
-
export const QUICK_SEARCH_DEFAULT_TEXT_BACK_COLOR =
|
|
6
|
-
export const
|
|
7
|
-
export const
|
|
8
|
-
export const
|
|
5
|
+
export const QUICK_SEARCH_DEFAULT_TEXT_BACK_COLOR = themeColorVar('quick-search-match');
|
|
6
|
+
export const QUICK_SEARCH_DEFAULT_TEXT_FORE_COLOR = themeColorVar('quick-search-match-foreground');
|
|
7
|
+
export const QUICK_SEARCH_DEFAULT_CURRENT_BACK_COLOR = themeColorVar('quick-search-current-match');
|
|
8
|
+
export const QUICK_SEARCH_DEFAULT_CURRENT_FORE_COLOR = themeColorVar('quick-search-current-match-foreground');
|
|
9
9
|
export const SYSTEM_THEMES = [LIGHT_THEME, DARK_THEME, OS_THEME];
|
|
10
10
|
export const THEME_DEFAULT_CURRENT_THEME = LIGHT_THEME;
|
|
@@ -31,4 +31,4 @@ export declare const inferAlertTypeFromDefinition: (alert: AlertDefinition, kind
|
|
|
31
31
|
* otherwise inferred from Rule / Schedule shape.
|
|
32
32
|
*/
|
|
33
33
|
export declare const getAlertType: (alert: AlertDefinition, kind?: ExpressionKind) => AlertType | null;
|
|
34
|
-
export declare const getAlertTypeText: (alertType: AlertType) => "" | "
|
|
34
|
+
export declare const getAlertTypeText: (alertType: AlertType) => "" | "Observable" | "Aggregation" | "Scheduled" | "Data Change" | "Relative Change" | "Data Validation" | "Row Change";
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { AdaptableApi } from '../../Api/AdaptableApi';
|
|
2
2
|
import { SettingsPanelDisplayOptions, SettingsPanelNavigation, SettingsPanelNavigationGroup, SettingsPanelOptions } from '../../AdaptableOptions/SettingsPanelOptions';
|
|
3
3
|
import { AdaptableIcon } from '../../types';
|
|
4
|
+
/** One Settings Panel sidebar module (visible for the current grid / entitlements). */
|
|
5
|
+
export type VisibleSettingsPanelNavigationItem = {
|
|
6
|
+
moduleName: string;
|
|
7
|
+
label: string;
|
|
8
|
+
};
|
|
9
|
+
export type VisibleSettingsPanelNavigationGroup = {
|
|
10
|
+
label: string;
|
|
11
|
+
items: VisibleSettingsPanelNavigationItem[];
|
|
12
|
+
};
|
|
4
13
|
/**
|
|
5
14
|
* True when `adaptableId` is the framework placeholder (`adaptable_id` or `adaptable_id_<n>`),
|
|
6
15
|
* not a developer-supplied human name.
|
|
@@ -41,3 +50,8 @@ export declare const getSettingsPanelOpenIcon: (resolvedIcon: SettingsPanelOptio
|
|
|
41
50
|
export declare const DEFAULT_SETTINGS_PANEL_NAVIGATION_GROUPS: SettingsPanelNavigationGroup[];
|
|
42
51
|
export declare const buildDefaultSettingsPanelNavigation: (customPanelNames?: string[]) => SettingsPanelNavigation;
|
|
43
52
|
export declare const resolveSettingsPanelNavigation: (api: AdaptableApi, settingsPanelOptions: SettingsPanelOptions) => SettingsPanelNavigation;
|
|
53
|
+
/**
|
|
54
|
+
* Settings Panel navigation groups containing only modules that appear in the
|
|
55
|
+
* panel sidebar (same rules as {@link useMenuItems} in AdaptablePopup).
|
|
56
|
+
*/
|
|
57
|
+
export declare function resolveVisibleSettingsPanelNavigationGroups(api: AdaptableApi): VisibleSettingsPanelNavigationGroup[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ADAPTABLE_ID } from '../Constants/GeneralConstants';
|
|
1
|
+
import { ADAPTABLE_ID, STANDALONE_MODULE_POPUPS } from '../Constants/GeneralConstants';
|
|
2
2
|
import { SettingsPanelFriendlyName } from '../Constants/ModuleConstants';
|
|
3
3
|
import StringExtensions from '../Extensions/StringExtensions';
|
|
4
4
|
export const isGenericAdaptableId = (adaptableId) => {
|
|
@@ -143,3 +143,39 @@ export const resolveSettingsPanelNavigation = (api, settingsPanelOptions) => {
|
|
|
143
143
|
warnLegacyNavigationOnce(api);
|
|
144
144
|
return convertLegacyFlatNavigationToGrouped(navigation);
|
|
145
145
|
};
|
|
146
|
+
export function resolveVisibleSettingsPanelNavigationGroups(api) {
|
|
147
|
+
const settingsPanelOptions = api.optionsApi.getAdaptableOptions().settingsPanelOptions;
|
|
148
|
+
const navigation = resolveSettingsPanelNavigation(api, settingsPanelOptions ?? {});
|
|
149
|
+
const allMenuItems = api.internalApi.getInternalState().SettingsPanelModuleEntries ?? [];
|
|
150
|
+
const visibleItems = allMenuItems.filter((item) => item.category !== 'General' &&
|
|
151
|
+
item.category !== 'CustomSettingsPanel' &&
|
|
152
|
+
item.category !== 'Group' &&
|
|
153
|
+
!STANDALONE_MODULE_POPUPS.includes(item.category) &&
|
|
154
|
+
item.isVisible);
|
|
155
|
+
const moduleService = api.internalApi.getModuleService();
|
|
156
|
+
const groups = [];
|
|
157
|
+
for (const group of navigation.groups) {
|
|
158
|
+
const items = [];
|
|
159
|
+
for (const moduleName of group.items) {
|
|
160
|
+
const moduleId = String(moduleName);
|
|
161
|
+
const customSettingsPanel = settingsPanelOptions?.customSettingsPanels?.find((panel) => panel.name === moduleId);
|
|
162
|
+
if (customSettingsPanel) {
|
|
163
|
+
items.push({ moduleName: moduleId, label: customSettingsPanel.name });
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
const menuItem = visibleItems.find((item) => item.category === moduleId);
|
|
167
|
+
if (!menuItem) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
items.push({
|
|
171
|
+
moduleName: moduleId,
|
|
172
|
+
label: menuItem.label ??
|
|
173
|
+
moduleService.getModuleFriendlyName(moduleId),
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (items.length) {
|
|
177
|
+
groups.push({ label: group.label ?? '', items });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return groups;
|
|
181
|
+
}
|