@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
package/src/setupDevTools.js
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
import { AG_GRID_VERSION } from './agGrid/AgGridModulesAdapter';
|
|
2
2
|
import { ADAPTABLE_VERSION } from './EnvVars';
|
|
3
|
-
import
|
|
3
|
+
import { resolveVisibleSettingsPanelNavigationGroups } from './Utilities/Helpers/SettingsPanelHelper';
|
|
4
|
+
import { isTransientReduxAction } from './Redux/Store/isTransientReduxAction';
|
|
5
|
+
import { isPivotLayout } from './Utilities/Helpers/Layouts/LayoutHelper';
|
|
4
6
|
import { debug } from '@infinite-table/infinite-react';
|
|
7
|
+
import { colorSchemeDark, colorSchemeLight, themeQuartz } from 'ag-grid-enterprise';
|
|
5
8
|
import { warnOnce } from './agGrid/AdaptableLogger';
|
|
6
9
|
let DEV_TOOLS_LISTENING_STARTED = false;
|
|
7
10
|
let DEV_TOOLS_READY = false;
|
|
8
|
-
const __ADAPTABLE_DEVTOOLS_EMITTER = new Emitter();
|
|
9
11
|
const LOG_LEVELS = ['info', 'success', 'warn', 'error', 'perf'];
|
|
12
|
+
const LOG_CHANNEL_BASES = ['Adaptable', 'LayoutManager'];
|
|
13
|
+
const MAX_LOG_ENTRIES_PER_INSTANCE = 500;
|
|
14
|
+
const MAX_ACTION_ENTRIES_PER_INSTANCE = 200;
|
|
15
|
+
const DEFAULT_LOG_LIMIT = 100;
|
|
16
|
+
const DEFAULT_ACTION_LIMIT = 50;
|
|
17
|
+
const DEVTOOLS_GLOBAL_NAME = '__ADAPTABLE_DEVTOOLS__';
|
|
18
|
+
const PROFILE_TRACKS_STORAGE_KEY = 'adaptableProfileTracks';
|
|
19
|
+
const DEBUG_STORAGE_KEY = 'debug';
|
|
10
20
|
function serializeForPostMessage(value) {
|
|
11
21
|
try {
|
|
12
22
|
const json = JSON.stringify(value);
|
|
@@ -17,8 +27,9 @@ function serializeForPostMessage(value) {
|
|
|
17
27
|
const seen = new WeakSet();
|
|
18
28
|
const json = JSON.stringify(value, (_key, val) => {
|
|
19
29
|
if (typeof val === 'object' && val !== null) {
|
|
20
|
-
if (seen.has(val))
|
|
30
|
+
if (seen.has(val)) {
|
|
21
31
|
return undefined;
|
|
32
|
+
}
|
|
22
33
|
seen.add(val);
|
|
23
34
|
}
|
|
24
35
|
return val;
|
|
@@ -34,7 +45,9 @@ function serializeAdaptableStateForPostMessage(state, parentKey) {
|
|
|
34
45
|
}
|
|
35
46
|
try {
|
|
36
47
|
const json = JSON.stringify(value);
|
|
37
|
-
|
|
48
|
+
if (json !== undefined) {
|
|
49
|
+
acc[key] = JSON.parse(json);
|
|
50
|
+
}
|
|
38
51
|
}
|
|
39
52
|
catch (_error) {
|
|
40
53
|
warnOnce(`Adaptable DevTools: skipping serializing state key "${parentKey ? `${parentKey}.` : ''}${key}"`);
|
|
@@ -66,23 +79,88 @@ function isMessageFromDevToolsContentScript(data) {
|
|
|
66
79
|
data.target === 'adaptable-page' &&
|
|
67
80
|
data.source.startsWith('adaptable-devtools-contentscript'));
|
|
68
81
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
82
|
+
const INSTANCE_REGISTRATIONS = new Map();
|
|
83
|
+
const LOG_BUFFERS = new Map();
|
|
84
|
+
const pendingGridRuntimeUpdates = new Map();
|
|
85
|
+
const GRID_RUNTIME_FALLBACK_DELAY_MS = 100;
|
|
86
|
+
function getRegistration(adaptableId) {
|
|
87
|
+
const registration = INSTANCE_REGISTRATIONS.get(adaptableId);
|
|
88
|
+
if (!registration || registration.instance?.isDestroyed) {
|
|
89
|
+
return undefined;
|
|
72
90
|
}
|
|
73
|
-
|
|
74
|
-
|
|
91
|
+
return registration;
|
|
92
|
+
}
|
|
93
|
+
function getRegisteredApi(adaptableId) {
|
|
94
|
+
return getRegistration(adaptableId)?.api;
|
|
95
|
+
}
|
|
96
|
+
function describeMountedInstances() {
|
|
97
|
+
const ids = [...INSTANCE_REGISTRATIONS.keys()];
|
|
98
|
+
return ids.length ? `Mounted instances: ${ids.map((id) => `"${id}"`).join(', ')}.` : 'No AdapTable instance is mounted.';
|
|
99
|
+
}
|
|
100
|
+
function resolveRegistration(adaptableId) {
|
|
101
|
+
if (adaptableId != null) {
|
|
102
|
+
const registration = getRegistration(adaptableId);
|
|
103
|
+
if (!registration) {
|
|
104
|
+
throw new Error(`Adaptable DevTools: no mounted AdapTable instance with adaptableId "${adaptableId}". ${describeMountedInstances()}`);
|
|
105
|
+
}
|
|
106
|
+
return registration;
|
|
107
|
+
}
|
|
108
|
+
const ids = [...INSTANCE_REGISTRATIONS.keys()];
|
|
109
|
+
if (ids.length === 1) {
|
|
110
|
+
return INSTANCE_REGISTRATIONS.get(ids[0]);
|
|
111
|
+
}
|
|
112
|
+
if (!ids.length) {
|
|
113
|
+
throw new Error('Adaptable DevTools: no AdapTable instance is mounted yet (wait for the grid to be ready, then retry).');
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`Adaptable DevTools: ${ids.length} AdapTable instances are mounted; pass an adaptableId. ${describeMountedInstances()}`);
|
|
116
|
+
}
|
|
117
|
+
let LOG_INTENT_LISTENING_STARTED = false;
|
|
118
|
+
function parseLogChannel(channel) {
|
|
119
|
+
const channelParts = channel.split(':');
|
|
120
|
+
const [channelBase, adaptableId] = channelParts;
|
|
121
|
+
if (!LOG_CHANNEL_BASES.includes(channelBase)) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
if (channelBase === 'LayoutManager' && adaptableId === 'Diffing') {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
if (!adaptableId) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const level = channelParts.find((part) => LOG_LEVELS.includes(part));
|
|
131
|
+
return { adaptableId, level: level ?? 'info' };
|
|
132
|
+
}
|
|
133
|
+
function bufferLogEntry(entry) {
|
|
134
|
+
let buffer = LOG_BUFFERS.get(entry.adaptableId);
|
|
135
|
+
if (!buffer) {
|
|
136
|
+
buffer = [];
|
|
137
|
+
LOG_BUFFERS.set(entry.adaptableId, buffer);
|
|
138
|
+
}
|
|
139
|
+
buffer.push(entry);
|
|
140
|
+
if (buffer.length > MAX_LOG_ENTRIES_PER_INSTANCE) {
|
|
141
|
+
buffer.splice(0, buffer.length - MAX_LOG_ENTRIES_PER_INSTANCE);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
function ensureLogIntentListening() {
|
|
145
|
+
if (LOG_INTENT_LISTENING_STARTED) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
LOG_INTENT_LISTENING_STARTED = true;
|
|
75
149
|
debug.onLogIntent('*', (logOptions) => {
|
|
76
150
|
const { channel, color, timestamp, args } = logOptions;
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
if (!['Adaptable', 'LayoutManager'].includes(channelBase)) {
|
|
151
|
+
const parsed = parseLogChannel(channel);
|
|
152
|
+
if (!parsed) {
|
|
80
153
|
return;
|
|
81
154
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
155
|
+
const formattedArgs = args.map((arg) => formatLogArgForPostMessage(arg));
|
|
156
|
+
bufferLogEntry({
|
|
157
|
+
timestamp,
|
|
158
|
+
adaptableId: parsed.adaptableId,
|
|
159
|
+
channel,
|
|
160
|
+
level: parsed.level,
|
|
161
|
+
args: formattedArgs,
|
|
162
|
+
});
|
|
163
|
+
if (!DEV_TOOLS_READY) {
|
|
86
164
|
return;
|
|
87
165
|
}
|
|
88
166
|
window.postMessage({
|
|
@@ -90,16 +168,29 @@ function ensureDevToolsReady() {
|
|
|
90
168
|
url: getPageUrlOfWindow(),
|
|
91
169
|
type: 'log',
|
|
92
170
|
payload: {
|
|
93
|
-
adaptableId,
|
|
171
|
+
adaptableId: parsed.adaptableId,
|
|
94
172
|
channel,
|
|
95
173
|
color,
|
|
96
|
-
level:
|
|
174
|
+
level: parsed.level,
|
|
97
175
|
timestamp,
|
|
98
|
-
args:
|
|
176
|
+
args: formattedArgs.map((arg) => serializeForPostMessage(arg)),
|
|
99
177
|
},
|
|
100
178
|
});
|
|
101
179
|
});
|
|
102
|
-
|
|
180
|
+
}
|
|
181
|
+
function ensureDevToolsReady() {
|
|
182
|
+
if (DEV_TOOLS_READY) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
DEV_TOOLS_READY = true;
|
|
186
|
+
console.log('Adaptable DevTools is listening for messages!');
|
|
187
|
+
for (const [adaptableId, registration] of INSTANCE_REGISTRATIONS) {
|
|
188
|
+
if (registration.instance?.isDestroyed) {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
postMountMessage(adaptableId, registration.api);
|
|
192
|
+
postStateChangeMessage(adaptableId, { api: registration.api });
|
|
193
|
+
}
|
|
103
194
|
}
|
|
104
195
|
function handleOpenSettingsPanelMessage(payload) {
|
|
105
196
|
const { adaptableId, moduleName } = payload ?? {};
|
|
@@ -107,52 +198,199 @@ function handleOpenSettingsPanelMessage(payload) {
|
|
|
107
198
|
console.warn('Adaptable DevTools: open-settings-panel message missing adaptableId');
|
|
108
199
|
return;
|
|
109
200
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
console.warn(`Adaptable DevTools: instance "${adaptableId}" is destroyed; cannot open settings panel`);
|
|
113
|
-
return;
|
|
201
|
+
try {
|
|
202
|
+
openSettingsPanel(adaptableId, moduleName);
|
|
114
203
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
if (!settingsPanelApi) {
|
|
118
|
-
console.warn(`Adaptable DevTools: settings panel is not available for "${adaptableId}" (instance not ready or destroyed)`);
|
|
119
|
-
return;
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.warn(error.message);
|
|
120
206
|
}
|
|
121
|
-
settingsPanelApi.openSettingsPanel(moduleName);
|
|
122
207
|
}
|
|
123
|
-
|
|
124
|
-
|
|
208
|
+
const THEME_PREVIEW_ATTR = 'data-ab-devtools-theme-preview';
|
|
209
|
+
function clearInlineAbVars(el) {
|
|
210
|
+
const style = el.style;
|
|
125
211
|
for (let i = style.length - 1; i >= 0; i--) {
|
|
126
212
|
const prop = style[i];
|
|
127
|
-
if (prop.startsWith('--ab-')) {
|
|
213
|
+
if (prop?.startsWith('--ab-') && !prop.startsWith('--ab-qs-')) {
|
|
128
214
|
style.removeProperty(prop);
|
|
129
215
|
}
|
|
130
216
|
}
|
|
217
|
+
}
|
|
218
|
+
let themeAliasMaps = null;
|
|
219
|
+
let themeAliasSheetCount = -1;
|
|
220
|
+
function collectThemeAliases() {
|
|
221
|
+
const sheetCount = document.styleSheets.length;
|
|
222
|
+
if (themeAliasMaps && themeAliasSheetCount === sheetCount) {
|
|
223
|
+
return themeAliasMaps;
|
|
224
|
+
}
|
|
225
|
+
const root = new Map();
|
|
226
|
+
const dark = new Map();
|
|
227
|
+
const visit = (rules) => {
|
|
228
|
+
for (let index = 0; index < rules.length; index++) {
|
|
229
|
+
const rule = rules[index];
|
|
230
|
+
const group = rule;
|
|
231
|
+
if (group.cssRules) {
|
|
232
|
+
visit(group.cssRules);
|
|
233
|
+
}
|
|
234
|
+
const styleRule = rule;
|
|
235
|
+
if (!styleRule.style || !styleRule.selectorText) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
const selector = styleRule.selectorText;
|
|
239
|
+
const isDark = selector.includes('ab--theme-dark');
|
|
240
|
+
const isRoot = selector.includes(':root') ||
|
|
241
|
+
selector.includes('ab--theme-light') ||
|
|
242
|
+
/(^|[^\w-])html([^\w-]|$)/.test(selector);
|
|
243
|
+
if (!isDark && !isRoot) {
|
|
244
|
+
continue;
|
|
245
|
+
}
|
|
246
|
+
const target = isDark ? dark : root;
|
|
247
|
+
for (let i = 0; i < styleRule.style.length; i++) {
|
|
248
|
+
const prop = styleRule.style[i];
|
|
249
|
+
if (!prop?.startsWith('--')) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
const value = styleRule.style.getPropertyValue(prop).trim();
|
|
253
|
+
if (value.includes('var(')) {
|
|
254
|
+
target.set(prop, value);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
for (let index = 0; index < document.styleSheets.length; index++) {
|
|
260
|
+
const sheet = document.styleSheets[index];
|
|
261
|
+
try {
|
|
262
|
+
visit(sheet.cssRules);
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
themeAliasMaps = { root, dark };
|
|
268
|
+
themeAliasSheetCount = sheetCount;
|
|
269
|
+
return themeAliasMaps;
|
|
270
|
+
}
|
|
271
|
+
let darkThemeProbe = null;
|
|
272
|
+
function themeDefaultStyle(variant) {
|
|
273
|
+
if (variant === 'light') {
|
|
274
|
+
return getComputedStyle(document.documentElement);
|
|
275
|
+
}
|
|
276
|
+
if (!darkThemeProbe) {
|
|
277
|
+
darkThemeProbe = document.createElement('div');
|
|
278
|
+
darkThemeProbe.className = 'ab--theme-dark';
|
|
279
|
+
darkThemeProbe.setAttribute('data-ab-devtools-theme-probe', '');
|
|
280
|
+
darkThemeProbe.style.cssText =
|
|
281
|
+
'position:absolute;width:0;height:0;overflow:hidden;pointer-events:none';
|
|
282
|
+
document.body.appendChild(darkThemeProbe);
|
|
283
|
+
}
|
|
284
|
+
return getComputedStyle(darkThemeProbe);
|
|
285
|
+
}
|
|
286
|
+
function installLiveAliases(el, variant) {
|
|
287
|
+
const { root, dark } = collectThemeAliases();
|
|
288
|
+
const defaults = themeDefaultStyle(variant);
|
|
289
|
+
const aliases = variant === 'dark' ? new Map([...root, ...dark]) : root;
|
|
290
|
+
for (const [name, raw] of aliases) {
|
|
291
|
+
const inline = el.style.getPropertyValue(name).trim();
|
|
292
|
+
const fallback = defaults.getPropertyValue(name).trim();
|
|
293
|
+
if (!inline || inline === raw || inline === fallback) {
|
|
294
|
+
el.style.setProperty(name, raw);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function clearDocumentThemePreview() {
|
|
299
|
+
clearInlineAbVars(document.documentElement);
|
|
300
|
+
}
|
|
301
|
+
function getInstanceThemeElements(adaptableId) {
|
|
302
|
+
const instance = getRegistration(adaptableId)?.instance;
|
|
303
|
+
if (!instance) {
|
|
304
|
+
return [];
|
|
305
|
+
}
|
|
306
|
+
const elements = [
|
|
307
|
+
instance.getAdaptableContainerElement(),
|
|
308
|
+
instance.getAgGridContainerElement(),
|
|
309
|
+
].filter((el) => el instanceof HTMLElement);
|
|
310
|
+
return [...new Set(elements)];
|
|
311
|
+
}
|
|
312
|
+
const originalAgGridThemes = new Map();
|
|
313
|
+
function applyAgGridPreviewTheme(adaptableId, variant) {
|
|
314
|
+
const instance = getRegistration(adaptableId)?.instance;
|
|
315
|
+
const gridApi = instance?.agGridAdapter.getAgGridApi();
|
|
316
|
+
if (!instance || instance.isDestroyed || !gridApi || gridApi.isDestroyed()) {
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (instance.agGridThemeAdapter.getAgGridThemeMode() === 'legacy') {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
if (!originalAgGridThemes.has(adaptableId)) {
|
|
323
|
+
originalAgGridThemes.set(adaptableId, gridApi.getGridOption('theme'));
|
|
324
|
+
}
|
|
325
|
+
const original = originalAgGridThemes.get(adaptableId);
|
|
326
|
+
const base = original && original !== 'legacy' && typeof original.withPart === 'function'
|
|
327
|
+
? original
|
|
328
|
+
: themeQuartz;
|
|
329
|
+
gridApi.setGridOption('theme', base.withPart(variant === 'dark' ? colorSchemeDark : colorSchemeLight));
|
|
330
|
+
}
|
|
331
|
+
function syncAgGridPreviewThemes(activeId, variant) {
|
|
332
|
+
applyAgGridPreviewTheme(activeId, variant);
|
|
333
|
+
}
|
|
334
|
+
function applyThemeVars(el, payload) {
|
|
335
|
+
clearInlineAbVars(el);
|
|
131
336
|
for (const [name, value] of Object.entries(payload.light)) {
|
|
132
337
|
if (value != null && value !== '') {
|
|
133
|
-
style.setProperty(name, String(value));
|
|
338
|
+
el.style.setProperty(name, String(value));
|
|
134
339
|
}
|
|
135
340
|
}
|
|
136
341
|
if (payload.variant === 'dark') {
|
|
137
342
|
for (const [name, value] of Object.entries(payload.dark)) {
|
|
138
343
|
if (value != null && value !== '') {
|
|
139
|
-
style.setProperty(name, String(value));
|
|
344
|
+
el.style.setProperty(name, String(value));
|
|
140
345
|
}
|
|
141
346
|
}
|
|
347
|
+
el.classList.add('ab--theme-dark');
|
|
348
|
+
}
|
|
349
|
+
else if (el.getAttribute(THEME_PREVIEW_ATTR) === 'dark') {
|
|
350
|
+
el.classList.remove('ab--theme-dark');
|
|
142
351
|
}
|
|
352
|
+
el.setAttribute(THEME_PREVIEW_ATTR, payload.variant);
|
|
353
|
+
installLiveAliases(el, payload.variant);
|
|
143
354
|
}
|
|
144
355
|
function handleThemeVarChangeMessage(payload) {
|
|
145
|
-
const { name, value } = payload ?? {};
|
|
146
|
-
if (!name) {
|
|
356
|
+
const { name, value, adaptableId } = payload ?? {};
|
|
357
|
+
if (!name || !adaptableId) {
|
|
147
358
|
return;
|
|
148
359
|
}
|
|
149
|
-
|
|
360
|
+
const targets = getInstanceThemeElements(adaptableId);
|
|
361
|
+
if (targets.length === 0) {
|
|
362
|
+
console.warn(`Adaptable DevTools: no theme container for "${adaptableId}"`);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const variant = payload.variant === 'dark' ? 'dark' : 'light';
|
|
366
|
+
clearDocumentThemePreview();
|
|
367
|
+
for (const el of targets) {
|
|
368
|
+
if (!el.hasAttribute(THEME_PREVIEW_ATTR)) {
|
|
369
|
+
el.setAttribute(THEME_PREVIEW_ATTR, variant);
|
|
370
|
+
}
|
|
371
|
+
installLiveAliases(el, variant);
|
|
372
|
+
el.style.setProperty(name, String(value ?? ''));
|
|
373
|
+
}
|
|
150
374
|
}
|
|
151
375
|
function handleApplyThemeMessage(payload) {
|
|
152
376
|
if (!payload || (payload.variant !== 'light' && payload.variant !== 'dark')) {
|
|
153
377
|
return;
|
|
154
378
|
}
|
|
155
|
-
|
|
379
|
+
const { adaptableId } = payload;
|
|
380
|
+
if (!adaptableId) {
|
|
381
|
+
console.warn('Adaptable DevTools: apply-theme message missing adaptableId');
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const targets = getInstanceThemeElements(adaptableId);
|
|
385
|
+
if (targets.length === 0) {
|
|
386
|
+
console.warn(`Adaptable DevTools: no theme container for "${adaptableId}"`);
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
clearDocumentThemePreview();
|
|
390
|
+
for (const el of targets) {
|
|
391
|
+
applyThemeVars(el, payload);
|
|
392
|
+
}
|
|
393
|
+
syncAgGridPreviewThemes(adaptableId, payload.variant);
|
|
156
394
|
}
|
|
157
395
|
function handleLoadVariantMessage(payload) {
|
|
158
396
|
const { adaptableId, variant } = payload ?? {};
|
|
@@ -160,7 +398,7 @@ function handleLoadVariantMessage(payload) {
|
|
|
160
398
|
console.warn('Adaptable DevTools: load-variant message missing adaptableId or variant');
|
|
161
399
|
return;
|
|
162
400
|
}
|
|
163
|
-
const api =
|
|
401
|
+
const api = getRegisteredApi(adaptableId);
|
|
164
402
|
if (!api) {
|
|
165
403
|
console.warn(`Adaptable DevTools: no registered instance for "${adaptableId}"`);
|
|
166
404
|
return;
|
|
@@ -179,23 +417,279 @@ function handleRestoreStateMessage(payload) {
|
|
|
179
417
|
console.warn('Adaptable DevTools: restore-state message missing adaptableId or state');
|
|
180
418
|
return;
|
|
181
419
|
}
|
|
182
|
-
|
|
183
|
-
if (!api) {
|
|
184
|
-
console.warn(`Adaptable DevTools: no registered instance for "${adaptableId}"`);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
void api.stateApi.internalApi.restoreState(state).catch((error) => {
|
|
420
|
+
void restoreState(adaptableId, state).catch((error) => {
|
|
188
421
|
console.error(`Adaptable DevTools: failed to restore state for "${adaptableId}"`, error);
|
|
189
422
|
});
|
|
190
423
|
}
|
|
424
|
+
function openSettingsPanel(adaptableId, moduleName) {
|
|
425
|
+
const { api } = resolveRegistration(adaptableId);
|
|
426
|
+
const settingsPanelApi = api?.settingsPanelApi;
|
|
427
|
+
if (!settingsPanelApi) {
|
|
428
|
+
throw new Error(`Adaptable DevTools: settings panel is not available for "${adaptableId}" (instance not ready or destroyed)`);
|
|
429
|
+
}
|
|
430
|
+
settingsPanelApi.openSettingsPanel(moduleName);
|
|
431
|
+
}
|
|
432
|
+
function restoreState(adaptableId, state) {
|
|
433
|
+
if (!state || typeof state !== 'object') {
|
|
434
|
+
return Promise.reject(new Error('Adaptable DevTools: restoreState needs a state object'));
|
|
435
|
+
}
|
|
436
|
+
const { api } = resolveRegistration(adaptableId);
|
|
437
|
+
return api.stateApi.internalApi.restoreState(state);
|
|
438
|
+
}
|
|
439
|
+
function buildGridRuntime(api) {
|
|
440
|
+
const selectedRowInfo = api.gridApi.getSelectedRowInfo();
|
|
441
|
+
return {
|
|
442
|
+
allRowsCount: api.gridApi.getRowCount(),
|
|
443
|
+
visibleRowsCount: api.gridApi.getVisibleRowCount(),
|
|
444
|
+
selectedRowsCount: selectedRowInfo?.gridRows?.length ?? 0,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
function buildInstanceSummary(api) {
|
|
448
|
+
const options = api.optionsApi.getAdaptableOptions();
|
|
449
|
+
const globalObject = typeof globalThis !== 'undefined' ? globalThis : window;
|
|
450
|
+
const licenseKey = globalObject.ADAPTABLE_LICENSE_KEY ||
|
|
451
|
+
options.licenseKey;
|
|
452
|
+
return {
|
|
453
|
+
licenseKey: licenseKey || undefined,
|
|
454
|
+
userName: api.optionsApi.getUserName(),
|
|
455
|
+
primaryKey: api.optionsApi.getPrimaryKey(),
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
function buildInstanceInfo(adaptableId, api) {
|
|
459
|
+
const { userName, primaryKey } = buildInstanceSummary(api);
|
|
460
|
+
return {
|
|
461
|
+
adaptableId,
|
|
462
|
+
adaptableVersion: ADAPTABLE_VERSION,
|
|
463
|
+
agGridVersion: AG_GRID_VERSION,
|
|
464
|
+
adaptableStateKey: api.optionsApi.getAdaptableStateKey(),
|
|
465
|
+
primaryKey,
|
|
466
|
+
userName,
|
|
467
|
+
gridRuntime: buildGridRuntime(api),
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
function getStateSnapshot(api) {
|
|
471
|
+
return api.stateApi.internalApi.getAllStateForDevTools
|
|
472
|
+
? api.stateApi.internalApi.getAllStateForDevTools()
|
|
473
|
+
: api.stateApi.getAllState();
|
|
474
|
+
}
|
|
475
|
+
function buildColumns(api) {
|
|
476
|
+
const calculated = new Set(api.calculatedColumnApi.getCalculatedColumns().map((c) => c.ColumnId));
|
|
477
|
+
const freeText = new Set(api.freeTextColumnApi.getFreeTextColumns().map((c) => c.ColumnId));
|
|
478
|
+
const action = new Set(api.actionColumnApi.getActionColumns().map((c) => c.columnId));
|
|
479
|
+
const visible = new Set(api.columnApi.getVisibleColumns().map((c) => c.columnId));
|
|
480
|
+
return api.columnApi.getColumns().map((column) => ({
|
|
481
|
+
id: column.columnId,
|
|
482
|
+
friendlyName: column.friendlyName,
|
|
483
|
+
dataType: column.dataType,
|
|
484
|
+
field: column.field,
|
|
485
|
+
columnTypes: column.columnTypes,
|
|
486
|
+
visible: visible.has(column.columnId),
|
|
487
|
+
readOnly: column.readOnly,
|
|
488
|
+
isPrimaryKey: column.isPrimaryKey,
|
|
489
|
+
isGrouped: column.isGrouped,
|
|
490
|
+
pinned: column.pinned,
|
|
491
|
+
isGeneratedRowGroupColumn: column.isGeneratedRowGroupColumn,
|
|
492
|
+
isGeneratedPivotResultColumn: column.isGeneratedPivotResultColumn,
|
|
493
|
+
isCalculatedColumn: calculated.has(column.columnId),
|
|
494
|
+
isFreeTextColumn: freeText.has(column.columnId),
|
|
495
|
+
isActionColumn: action.has(column.columnId),
|
|
496
|
+
}));
|
|
497
|
+
}
|
|
498
|
+
function buildGridInfo(adaptableId, api) {
|
|
499
|
+
const { licenseKey, userName, primaryKey } = buildInstanceSummary(api);
|
|
500
|
+
const currentLayout = api.layoutApi.getCurrentLayout();
|
|
501
|
+
const isPivot = isPivotLayout(currentLayout);
|
|
502
|
+
const selectedRowInfo = api.gridApi.getSelectedRowInfo();
|
|
503
|
+
const available = [];
|
|
504
|
+
const unavailable = [];
|
|
505
|
+
api.internalApi.getModules().forEach((module, moduleName) => {
|
|
506
|
+
(module.isModuleAvailable() ? available : unavailable).push(moduleName);
|
|
507
|
+
});
|
|
508
|
+
return {
|
|
509
|
+
adaptableId,
|
|
510
|
+
adaptableVersion: ADAPTABLE_VERSION,
|
|
511
|
+
agGridVersion: AG_GRID_VERSION,
|
|
512
|
+
adaptableStateKey: api.optionsApi.getAdaptableStateKey(),
|
|
513
|
+
userName,
|
|
514
|
+
primaryKey,
|
|
515
|
+
isAutogeneratedPrimaryKey: api.optionsApi.isAutogeneratePrimaryKey(),
|
|
516
|
+
licenseKey,
|
|
517
|
+
layout: {
|
|
518
|
+
name: api.layoutApi.getCurrentLayoutName(),
|
|
519
|
+
type: isPivot ? 'Pivot' : 'Table',
|
|
520
|
+
rowGroups: api.layoutApi.getCurrentRowGroupsColumnIds() ?? [],
|
|
521
|
+
pivotColumns: isPivot ? (currentLayout.PivotColumns ?? []) : [],
|
|
522
|
+
sorts: (api.gridApi.getColumnSorts() ?? []).map((sort) => ({
|
|
523
|
+
columnId: sort.ColumnId,
|
|
524
|
+
sortOrder: sort.SortOrder,
|
|
525
|
+
})),
|
|
526
|
+
},
|
|
527
|
+
columnFilters: api.filterApi.columnFilterApi.columnFiltersToString(api.filterApi.columnFilterApi.getColumnFilters()),
|
|
528
|
+
gridFilter: api.filterApi.gridFilterApi.getCurrentGridFilterExpression() || undefined,
|
|
529
|
+
rows: {
|
|
530
|
+
all: api.gridApi.getRowCount(),
|
|
531
|
+
visible: api.gridApi.getVisibleRowCount(),
|
|
532
|
+
selected: selectedRowInfo?.gridRows?.length ?? 0,
|
|
533
|
+
},
|
|
534
|
+
columns: {
|
|
535
|
+
all: api.gridApi.getColumnCount(),
|
|
536
|
+
visible: api.gridApi.getVisibleColumnCount(),
|
|
537
|
+
calculated: api.calculatedColumnApi.getCalculatedColumns().map((c) => c.ColumnId),
|
|
538
|
+
freeText: api.freeTextColumnApi.getFreeTextColumns().map((c) => c.ColumnId),
|
|
539
|
+
action: api.actionColumnApi.getActionColumns().map((c) => c.columnId),
|
|
540
|
+
},
|
|
541
|
+
modules: { available, unavailable },
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
function getLocalStorage() {
|
|
545
|
+
try {
|
|
546
|
+
return typeof localStorage !== 'undefined' ? localStorage : undefined;
|
|
547
|
+
}
|
|
548
|
+
catch {
|
|
549
|
+
return undefined;
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
const DEVTOOLS_HELP = `AdapTable DevTools in-page API (window.${DEVTOOLS_GLOBAL_NAME}). Every method returns plain JSON unless noted.
|
|
553
|
+
Omit adaptableId when one instance is mounted.
|
|
554
|
+
|
|
555
|
+
listInstances() -> [{ adaptableId, adaptableVersion, agGridVersion, primaryKey, userName, gridRuntime }]
|
|
556
|
+
getGridInfo(id?) -> versions, layout, filters, row/column counts, modules (the Settings Panel "Grid Info" facts)
|
|
557
|
+
getState(id?, section?) -> full AdapTable State, or one section such as 'Layout' or 'FormatColumn'
|
|
558
|
+
getPersistentState(id?) -> the user state AdapTable persists; pass it to the MCP check_state / migrate_state tools
|
|
559
|
+
getColumns(id?) -> [{ id, friendlyName, dataType, visible, ... }]; { id, dataType } is the MCP "columns" input
|
|
560
|
+
getLogs(id?, { level?, channel?, limit? }) -> recent AdapTable log messages, buffered without localStorage.debug
|
|
561
|
+
getRecentActions(id?, limit?) -> recent state-changing actions
|
|
562
|
+
restoreState(id, state) -> Promise; restores a snapshot from getState()/getPersistentState()
|
|
563
|
+
openSettingsPanel(id?, moduleName?) -> opens the Settings Panel (e.g. 'Layout', 'FormatColumn')
|
|
564
|
+
setLogging(pattern | null) -> sets localStorage.debug (e.g. 'Adaptable:<id>:*'); returns the previous value
|
|
565
|
+
enableProfiling(enabled?) -> toggles localStorage.adaptableProfileTracks
|
|
566
|
+
getApi(id?) -> the live AdaptableApi (not serializable)
|
|
567
|
+
|
|
568
|
+
Docs: https://www.adaptabletools.com/docs/dev-guide-support-devtools`;
|
|
569
|
+
function createDevToolsGlobal() {
|
|
570
|
+
return {
|
|
571
|
+
help() {
|
|
572
|
+
return DEVTOOLS_HELP;
|
|
573
|
+
},
|
|
574
|
+
listInstances() {
|
|
575
|
+
const result = [];
|
|
576
|
+
for (const [adaptableId, registration] of INSTANCE_REGISTRATIONS) {
|
|
577
|
+
if (registration.instance?.isDestroyed) {
|
|
578
|
+
continue;
|
|
579
|
+
}
|
|
580
|
+
result.push(buildInstanceInfo(adaptableId, registration.api));
|
|
581
|
+
}
|
|
582
|
+
return result;
|
|
583
|
+
},
|
|
584
|
+
getState(adaptableId, section) {
|
|
585
|
+
const { api } = resolveRegistration(adaptableId);
|
|
586
|
+
const state = serializeAdaptableStateForPostMessage(getStateSnapshot(api));
|
|
587
|
+
if (section == null) {
|
|
588
|
+
return state;
|
|
589
|
+
}
|
|
590
|
+
if (!(section in state)) {
|
|
591
|
+
throw new Error(`Adaptable DevTools: unknown state section "${String(section)}". Sections: ${Object.keys(state).join(', ')}`);
|
|
592
|
+
}
|
|
593
|
+
return state[section];
|
|
594
|
+
},
|
|
595
|
+
getPersistentState(adaptableId) {
|
|
596
|
+
const { api } = resolveRegistration(adaptableId);
|
|
597
|
+
return serializeForPostMessage(api.stateApi.getPersistentState());
|
|
598
|
+
},
|
|
599
|
+
getColumns(adaptableId) {
|
|
600
|
+
const { api } = resolveRegistration(adaptableId);
|
|
601
|
+
return serializeForPostMessage(buildColumns(api));
|
|
602
|
+
},
|
|
603
|
+
getGridInfo(adaptableId) {
|
|
604
|
+
const registration = resolveRegistration(adaptableId);
|
|
605
|
+
const id = adaptableId ?? registration.api.optionsApi.getAdaptableId();
|
|
606
|
+
return serializeForPostMessage(buildGridInfo(id, registration.api));
|
|
607
|
+
},
|
|
608
|
+
getLogs(adaptableId, options) {
|
|
609
|
+
const registration = resolveRegistration(adaptableId);
|
|
610
|
+
const id = adaptableId ?? registration.api.optionsApi.getAdaptableId();
|
|
611
|
+
const { level, channel, limit = DEFAULT_LOG_LIMIT } = options ?? {};
|
|
612
|
+
const levels = level == null ? null : new Set(Array.isArray(level) ? level : [level]);
|
|
613
|
+
const entries = (LOG_BUFFERS.get(id) ?? []).filter((entry) => (!levels || levels.has(entry.level)) && (!channel || entry.channel.includes(channel)));
|
|
614
|
+
return entries.slice(Math.max(0, entries.length - limit)).map((entry) => ({ ...entry }));
|
|
615
|
+
},
|
|
616
|
+
getRecentActions(adaptableId, limit = DEFAULT_ACTION_LIMIT) {
|
|
617
|
+
const { actions } = resolveRegistration(adaptableId);
|
|
618
|
+
return actions.slice(Math.max(0, actions.length - limit)).map((entry) => ({ ...entry }));
|
|
619
|
+
},
|
|
620
|
+
restoreState(adaptableId, state) {
|
|
621
|
+
return restoreState(adaptableId, state);
|
|
622
|
+
},
|
|
623
|
+
openSettingsPanel(adaptableId, moduleName) {
|
|
624
|
+
openSettingsPanel(adaptableId, moduleName);
|
|
625
|
+
},
|
|
626
|
+
setLogging(pattern) {
|
|
627
|
+
const storage = getLocalStorage();
|
|
628
|
+
if (!storage) {
|
|
629
|
+
throw new Error('Adaptable DevTools: localStorage is not available');
|
|
630
|
+
}
|
|
631
|
+
const previous = storage.getItem(DEBUG_STORAGE_KEY);
|
|
632
|
+
if (pattern == null || pattern === '') {
|
|
633
|
+
storage.removeItem(DEBUG_STORAGE_KEY);
|
|
634
|
+
}
|
|
635
|
+
else {
|
|
636
|
+
storage.setItem(DEBUG_STORAGE_KEY, pattern);
|
|
637
|
+
}
|
|
638
|
+
return previous;
|
|
639
|
+
},
|
|
640
|
+
enableProfiling(enabled = true) {
|
|
641
|
+
const storage = getLocalStorage();
|
|
642
|
+
if (!storage) {
|
|
643
|
+
throw new Error('Adaptable DevTools: localStorage is not available');
|
|
644
|
+
}
|
|
645
|
+
if (enabled) {
|
|
646
|
+
storage.setItem(PROFILE_TRACKS_STORAGE_KEY, 'true');
|
|
647
|
+
}
|
|
648
|
+
else {
|
|
649
|
+
storage.removeItem(PROFILE_TRACKS_STORAGE_KEY);
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
getApi(adaptableId) {
|
|
653
|
+
return resolveRegistration(adaptableId).api;
|
|
654
|
+
},
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
function ensureDevToolsGlobal() {
|
|
658
|
+
if (typeof window === 'undefined') {
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
if (!window[DEVTOOLS_GLOBAL_NAME]) {
|
|
662
|
+
Object.defineProperty(window, DEVTOOLS_GLOBAL_NAME, {
|
|
663
|
+
value: createDevToolsGlobal(),
|
|
664
|
+
writable: false,
|
|
665
|
+
configurable: true,
|
|
666
|
+
enumerable: false,
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
function setupDevToolsOnLoad() {
|
|
671
|
+
if (typeof window === 'undefined') {
|
|
672
|
+
return;
|
|
673
|
+
}
|
|
674
|
+
ensureDevToolsGlobal();
|
|
675
|
+
ensureLogIntentListening();
|
|
676
|
+
}
|
|
677
|
+
setupDevToolsOnLoad();
|
|
191
678
|
export function listenForDevTools(adaptableInstance) {
|
|
192
|
-
if (typeof window
|
|
679
|
+
if (typeof window === 'undefined') {
|
|
680
|
+
return;
|
|
681
|
+
}
|
|
682
|
+
setupDevToolsOnLoad();
|
|
683
|
+
if (!DEV_TOOLS_LISTENING_STARTED) {
|
|
193
684
|
DEV_TOOLS_LISTENING_STARTED = true;
|
|
194
685
|
window.addEventListener('message', (event) => {
|
|
686
|
+
if (event.source !== window) {
|
|
687
|
+
return;
|
|
688
|
+
}
|
|
195
689
|
if (!isMessageFromDevToolsContentScript(event.data)) {
|
|
196
690
|
return;
|
|
197
691
|
}
|
|
198
|
-
|
|
692
|
+
ensureDevToolsReady();
|
|
199
693
|
const handlers = {
|
|
200
694
|
'restore-state': handleRestoreStateMessage,
|
|
201
695
|
'open-settings-panel': handleOpenSettingsPanelMessage,
|
|
@@ -206,28 +700,12 @@ export function listenForDevTools(adaptableInstance) {
|
|
|
206
700
|
handlers[event.data.type]?.(event.data.payload);
|
|
207
701
|
});
|
|
208
702
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
registerAdaptableInstanceInDevTools(adaptableOptions.adaptableId, { api }, adaptableInstance);
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
const REGISTERED_ADAPTABLE_IDS = new Set();
|
|
219
|
-
const REGISTERED_ADAPTABLE_APIS = new Map();
|
|
220
|
-
const REGISTERED_ADAPTABLE_INSTANCES = new Map();
|
|
221
|
-
const pendingGridRuntimeUpdates = new Map();
|
|
222
|
-
const GRID_RUNTIME_FALLBACK_DELAY_MS = 100;
|
|
223
|
-
const INSTANCE_REGISTRATIONS = new Map();
|
|
224
|
-
function buildGridRuntime(api) {
|
|
225
|
-
const selectedRowInfo = api.gridApi.getSelectedRowInfo();
|
|
226
|
-
return {
|
|
227
|
-
allRowsCount: api.gridApi.getRowCount(),
|
|
228
|
-
visibleRowsCount: api.gridApi.getVisibleRowCount(),
|
|
229
|
-
selectedRowsCount: selectedRowInfo?.gridRows?.length ?? 0,
|
|
230
|
-
};
|
|
703
|
+
const { api, adaptableOptions } = adaptableInstance;
|
|
704
|
+
if (!api || !adaptableOptions) {
|
|
705
|
+
console.error('Cannot register Adaptable instance in DevTools because it is not ready', adaptableInstance);
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
registerAdaptableInstanceInDevTools(adaptableOptions.adaptableId, api, adaptableInstance);
|
|
231
709
|
}
|
|
232
710
|
function postMountMessage(adaptableId, api) {
|
|
233
711
|
window.postMessage(buildMessageForExtension({
|
|
@@ -235,7 +713,8 @@ function postMountMessage(adaptableId, api) {
|
|
|
235
713
|
adaptableId,
|
|
236
714
|
adaptableVersion: ADAPTABLE_VERSION,
|
|
237
715
|
agGridVersion: AG_GRID_VERSION,
|
|
238
|
-
|
|
716
|
+
...buildInstanceSummary(api),
|
|
717
|
+
settingsPanelNavigation: resolveVisibleSettingsPanelNavigationGroups(api),
|
|
239
718
|
}));
|
|
240
719
|
}
|
|
241
720
|
function cancelScheduledGridRuntimeUpdate(adaptableId) {
|
|
@@ -253,28 +732,31 @@ function scheduleGridRuntimeUpdate(adaptableId, api, delayMs = GRID_RUNTIME_FALL
|
|
|
253
732
|
}, delayMs));
|
|
254
733
|
}
|
|
255
734
|
function postStateChangeMessage(adaptableId, options) {
|
|
256
|
-
const api = options?.api ??
|
|
735
|
+
const api = options?.api ?? getRegisteredApi(adaptableId);
|
|
257
736
|
if (!api) {
|
|
258
737
|
return;
|
|
259
738
|
}
|
|
260
|
-
const state = api.stateApi.internalApi.getAllStateForDevTools
|
|
261
|
-
? api.stateApi.internalApi.getAllStateForDevTools()
|
|
262
|
-
: api.stateApi.getAllState();
|
|
263
739
|
window.postMessage(buildMessageForExtension({
|
|
264
740
|
type: 'state-change',
|
|
265
741
|
adaptableId,
|
|
266
|
-
state: serializeAdaptableStateForPostMessage(
|
|
742
|
+
state: serializeAdaptableStateForPostMessage(getStateSnapshot(api)),
|
|
267
743
|
actionName: options?.actionName,
|
|
744
|
+
...buildInstanceSummary(api),
|
|
745
|
+
settingsPanelNavigation: resolveVisibleSettingsPanelNavigationGroups(api),
|
|
268
746
|
}));
|
|
269
747
|
if (options?.api) {
|
|
270
748
|
scheduleGridRuntimeUpdate(adaptableId, options.api);
|
|
271
749
|
}
|
|
272
750
|
}
|
|
273
751
|
function postGridRuntimeUpdate(adaptableId, api) {
|
|
752
|
+
if (!DEV_TOOLS_READY) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
274
755
|
window.postMessage(buildMessageForExtension({
|
|
275
756
|
type: 'state-change',
|
|
276
757
|
adaptableId,
|
|
277
758
|
gridRuntime: buildGridRuntime(api),
|
|
759
|
+
...buildInstanceSummary(api),
|
|
278
760
|
}));
|
|
279
761
|
}
|
|
280
762
|
function detachAdaptableInstanceListeners(adaptableId) {
|
|
@@ -284,13 +766,13 @@ function detachAdaptableInstanceListeners(adaptableId) {
|
|
|
284
766
|
registration.unsubscribe();
|
|
285
767
|
INSTANCE_REGISTRATIONS.delete(adaptableId);
|
|
286
768
|
}
|
|
287
|
-
REGISTERED_ADAPTABLE_IDS.delete(adaptableId);
|
|
288
|
-
REGISTERED_ADAPTABLE_APIS.delete(adaptableId);
|
|
289
|
-
REGISTERED_ADAPTABLE_INSTANCES.delete(adaptableId);
|
|
290
769
|
}
|
|
291
770
|
function unregisterAdaptableInstanceFromDevTools(adaptableId) {
|
|
292
771
|
detachAdaptableInstanceListeners(adaptableId);
|
|
293
|
-
|
|
772
|
+
LOG_BUFFERS.delete(adaptableId);
|
|
773
|
+
if (DEV_TOOLS_READY) {
|
|
774
|
+
window.postMessage(buildMessageForExtension({ type: 'unmount', adaptableId }));
|
|
775
|
+
}
|
|
294
776
|
}
|
|
295
777
|
const messageBase = {
|
|
296
778
|
source: 'adaptable-page',
|
|
@@ -324,6 +806,9 @@ function buildMessageForExtension(params) {
|
|
|
324
806
|
adaptableVersion: payload?.adaptableVersion,
|
|
325
807
|
agGridVersion: payload?.agGridVersion,
|
|
326
808
|
licenseKey: payload?.licenseKey,
|
|
809
|
+
userName: payload?.userName,
|
|
810
|
+
primaryKey: payload?.primaryKey,
|
|
811
|
+
settingsPanelNavigation: payload?.settingsPanelNavigation,
|
|
327
812
|
},
|
|
328
813
|
};
|
|
329
814
|
}
|
|
@@ -337,6 +822,10 @@ function buildMessageForExtension(params) {
|
|
|
337
822
|
state: payload?.state,
|
|
338
823
|
actionName: payload?.actionName,
|
|
339
824
|
gridRuntime: payload?.gridRuntime,
|
|
825
|
+
licenseKey: payload?.licenseKey,
|
|
826
|
+
userName: payload?.userName,
|
|
827
|
+
primaryKey: payload?.primaryKey,
|
|
828
|
+
settingsPanelNavigation: payload?.settingsPanelNavigation,
|
|
340
829
|
},
|
|
341
830
|
};
|
|
342
831
|
}
|
|
@@ -351,30 +840,34 @@ function buildMessageForExtension(params) {
|
|
|
351
840
|
};
|
|
352
841
|
return message;
|
|
353
842
|
}
|
|
354
|
-
function
|
|
355
|
-
|
|
356
|
-
if (
|
|
357
|
-
|
|
843
|
+
function recordAction(registration, actionName) {
|
|
844
|
+
registration.actions.push({ timestamp: Date.now(), actionName });
|
|
845
|
+
if (registration.actions.length > MAX_ACTION_ENTRIES_PER_INSTANCE) {
|
|
846
|
+
registration.actions.splice(0, registration.actions.length - MAX_ACTION_ENTRIES_PER_INSTANCE);
|
|
358
847
|
}
|
|
359
|
-
postStateChangeMessage(adaptableId, { api });
|
|
360
848
|
}
|
|
361
|
-
function registerAdaptableInstanceInDevTools(adaptableId,
|
|
362
|
-
const { api } = options;
|
|
849
|
+
function registerAdaptableInstanceInDevTools(adaptableId, api, adaptableInstance) {
|
|
363
850
|
detachAdaptableInstanceListeners(adaptableId);
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
851
|
+
const registration = {
|
|
852
|
+
api,
|
|
853
|
+
instance: adaptableInstance,
|
|
854
|
+
actions: [],
|
|
855
|
+
unsubscribe: () => { },
|
|
856
|
+
};
|
|
370
857
|
const onStateChange = (info) => {
|
|
371
|
-
|
|
858
|
+
if (isTransientReduxAction(info.actionName)) {
|
|
859
|
+
return;
|
|
860
|
+
}
|
|
861
|
+
recordAction(registration, info.actionName);
|
|
862
|
+
if (DEV_TOOLS_READY) {
|
|
863
|
+
postStateChangeMessage(adaptableId, { actionName: info.actionName, api });
|
|
864
|
+
}
|
|
372
865
|
};
|
|
373
866
|
const onStateReloaded = () => {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
api
|
|
377
|
-
}
|
|
867
|
+
recordAction(registration, 'AdaptableStateReloaded');
|
|
868
|
+
if (DEV_TOOLS_READY) {
|
|
869
|
+
postStateChangeMessage(adaptableId, { actionName: 'AdaptableStateReloaded', api });
|
|
870
|
+
}
|
|
378
871
|
};
|
|
379
872
|
const unsubscribeStateChanged = api.eventApi.on('AdaptableStateChanged', onStateChange);
|
|
380
873
|
const unsubscribeStateReloaded = api.eventApi.on('AdaptableStateReloaded', onStateReloaded);
|
|
@@ -384,21 +877,21 @@ function registerAdaptableInstanceInDevTools(adaptableId, options, adaptableInst
|
|
|
384
877
|
const unsubscribeDestroy = api.eventApi.on('AdaptableDestroy', () => {
|
|
385
878
|
unregisterAdaptableInstanceFromDevTools(adaptableId);
|
|
386
879
|
});
|
|
387
|
-
const
|
|
388
|
-
const unsubscribeFiltersApplied = adaptableGrid?._on('AdapTableFiltersApplied', () => {
|
|
880
|
+
const unsubscribeFiltersApplied = adaptableInstance._on('AdapTableFiltersApplied', () => {
|
|
389
881
|
cancelScheduledGridRuntimeUpdate(adaptableId);
|
|
390
882
|
postGridRuntimeUpdate(adaptableId, api);
|
|
391
883
|
});
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
884
|
+
registration.unsubscribe = () => {
|
|
885
|
+
unsubscribeStateChanged();
|
|
886
|
+
unsubscribeStateReloaded();
|
|
887
|
+
unsubscribeRowSelectionChanged();
|
|
888
|
+
unsubscribeFiltersApplied?.();
|
|
889
|
+
unsubscribeDestroy();
|
|
890
|
+
};
|
|
891
|
+
INSTANCE_REGISTRATIONS.set(adaptableId, registration);
|
|
892
|
+
if (DEV_TOOLS_READY) {
|
|
893
|
+
console.log(`Registering instance "${adaptableId}" into Adaptable DevTools`);
|
|
894
|
+
postMountMessage(adaptableId, api);
|
|
895
|
+
postStateChangeMessage(adaptableId, { api });
|
|
896
|
+
}
|
|
404
897
|
}
|