@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.
Files changed (138) hide show
  1. package/devtools.d.ts +182 -1
  2. package/index.css +300 -275
  3. package/package.json +2 -1
  4. package/src/AdaptableInterfaces/IAdaptable.d.ts +4 -4
  5. package/src/AdaptableOptions/DefaultAdaptableOptions.js +5 -5
  6. package/src/AdaptableOptions/FlashingCellOptions.d.ts +3 -3
  7. package/src/AdaptableOptions/SettingsPanelOptions.d.ts +6 -4
  8. package/src/AdaptableOptions/StateOptions.d.ts +37 -13
  9. package/src/AdaptableOptions/UserInterfaceOptions.d.ts +4 -6
  10. package/src/AdaptableState/AdaptableState.d.ts +2 -0
  11. package/src/AdaptableState/QuickSearchState.d.ts +4 -0
  12. package/src/AdaptableState/StyledColumns/GradientStyle.d.ts +4 -0
  13. package/src/Api/Implementation/ColumnScopeApiImpl.js +3 -3
  14. package/src/Api/Implementation/QuickSearchApiImpl.js +2 -2
  15. package/src/Api/Implementation/StateApiImpl.d.ts +1 -1
  16. package/src/Api/Implementation/StateApiImpl.js +4 -3
  17. package/src/Api/Implementation/UserInterfaceApiImpl.d.ts +0 -1
  18. package/src/Api/Implementation/UserInterfaceApiImpl.js +9 -15
  19. package/src/Api/Internal/AdaptableInternalApi.js +5 -3
  20. package/src/Api/Internal/CalculatedColumnInternalApi.js +1 -1
  21. package/src/Api/Internal/StateInternalApi.d.ts +1 -1
  22. package/src/Api/Internal/StateInternalApi.js +6 -5
  23. package/src/Api/StateApi.d.ts +2 -2
  24. package/src/Api/UserInterfaceApi.d.ts +0 -4
  25. package/src/Redux/ActionsReducers/QuickSearchRedux.d.ts +9 -4
  26. package/src/Redux/ActionsReducers/QuickSearchRedux.js +12 -7
  27. package/src/Redux/Store/AdaptableReduxLocalStorageEngine.d.ts +8 -0
  28. package/src/Redux/Store/AdaptableReduxLocalStorageEngine.js +12 -12
  29. package/src/Redux/Store/AdaptableStore.d.ts +8 -5
  30. package/src/Redux/Store/AdaptableStore.js +51 -21
  31. package/src/Redux/Store/Interface/IAdaptableStore.d.ts +5 -5
  32. package/src/Redux/Store/Interface/IStorageEngine.d.ts +4 -4
  33. package/src/Redux/Store/StateOptionsGuards.d.ts +58 -0
  34. package/src/Redux/Store/StateOptionsGuards.js +112 -0
  35. package/src/Redux/Store/isTransientReduxAction.d.ts +5 -0
  36. package/src/Redux/Store/isTransientReduxAction.js +19 -0
  37. package/src/Utilities/Constants/DocumentationLinkConstants.d.ts +1 -0
  38. package/src/Utilities/Constants/DocumentationLinkConstants.js +1 -0
  39. package/src/Utilities/Constants/ReduxConstants.d.ts +2 -2
  40. package/src/Utilities/Constants/ReduxConstants.js +5 -5
  41. package/src/Utilities/Helpers/AlertTypeHelper.d.ts +1 -1
  42. package/src/Utilities/Helpers/SettingsPanelHelper.d.ts +14 -0
  43. package/src/Utilities/Helpers/SettingsPanelHelper.js +37 -1
  44. package/src/Utilities/Helpers/UIHelper.d.ts +12 -14
  45. package/src/Utilities/Helpers/UIHelper.js +12 -35
  46. package/src/Utilities/ObjectFactory.js +3 -3
  47. package/src/View/Components/Popups/AdaptablePopup/Navigation.js +9 -11
  48. package/src/View/Components/StyleComponent.js +2 -2
  49. package/src/View/Dashboard/Dashboard.d.ts +1 -1
  50. package/src/View/Dashboard/Dashboard.js +1 -1
  51. package/src/View/Dashboard/DashboardPopupSections.js +1 -1
  52. package/src/View/GridInfo/GridInfoPopup.js +62 -25
  53. package/src/View/QuickSearch/QuickSearchInput.js +1 -1
  54. package/src/View/QuickSearch/QuickSearchPopup.d.ts +1 -1
  55. package/src/View/QuickSearch/QuickSearchPopup.js +1 -1
  56. package/src/View/QuickSearch/Utilities/useQuickSearchDebounced.d.ts +2 -2
  57. package/src/View/StyledColumn/RangesComponent.js +13 -16
  58. package/src/View/StyledColumn/Wizard/BadgePillStyleEditor.d.ts +0 -2
  59. package/src/View/StyledColumn/Wizard/BadgePillStyleEditor.js +2 -2
  60. package/src/View/StyledColumn/Wizard/StyledColumnBadgeSection.js +2 -3
  61. package/src/View/StyledColumn/Wizard/StyledColumnSliceStyleEditors.d.ts +0 -3
  62. package/src/View/StyledColumn/Wizard/StyledColumnSliceStyleEditors.js +3 -3
  63. package/src/View/StyledColumn/Wizard/StyledColumnSparklineSettingsSection.js +7 -11
  64. package/src/View/StyledColumn/Wizard/StyledColumnWizardBulletSection.js +6 -6
  65. package/src/View/StyledColumn/Wizard/StyledColumnWizardGradientSection.js +2 -2
  66. package/src/View/StyledColumn/Wizard/StyledColumnWizardIconSection.js +2 -2
  67. package/src/View/StyledColumn/Wizard/StyledColumnWizardRangeBarSection.js +8 -8
  68. package/src/View/StyledColumn/Wizard/StyledColumnWizardRatingSection.js +4 -4
  69. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/StyledColumnWizardRangesSection.js +2 -2
  70. package/src/View/StyledColumn/Wizard/StyledColumnWizardStyleSection/StyledColumnWizardStyleSection.js +4 -4
  71. package/src/View/Wizard/CollapsibleWizardCard.d.ts +3 -1
  72. package/src/View/Wizard/CollapsibleWizardCard.js +17 -9
  73. package/src/agGrid/AdaptableAgGrid.d.ts +4 -4
  74. package/src/agGrid/AdaptableAgGrid.js +2 -0
  75. package/src/agGrid/AgGridColumnAdapter.d.ts +1 -1
  76. package/src/agGrid/AgGridColumnAdapter.js +4 -4
  77. package/src/components/ColorField/index.d.ts +14 -0
  78. package/src/components/ColorField/index.js +6 -0
  79. package/src/components/aql/QueryBuilder/QueryBuilderInputs.js +1 -1
  80. package/src/env.js +2 -2
  81. package/src/layout-manager/src/normalizeLayoutModel.d.ts +1 -1
  82. package/src/layout-manager/src/simplifyLayoutModel.d.ts +1 -1
  83. package/src/migration/AdaptableUpgradeHelper.d.ts +7 -2
  84. package/src/migration/VersionUpgrade17.js +13 -8
  85. package/src/migration/VersionUpgrade24.d.ts +9 -0
  86. package/src/migration/VersionUpgrade24.js +27 -0
  87. package/src/setupDevTools.js +605 -112
  88. package/src/types.d.ts +1 -1
  89. package/tsconfig.esm.tsbuildinfo +1 -1
  90. package/vendor/components/Button/index.d.ts +1 -1
  91. package/vendor/components/Button/index.d.ts.map +1 -1
  92. package/vendor/components/Button/index.js.map +1 -1
  93. package/vendor/components/CheckBox/index.d.ts +1 -1
  94. package/vendor/components/CheckBox/index.d.ts.map +1 -1
  95. package/vendor/components/CheckBox/index.js.map +1 -1
  96. package/vendor/components/ColorField/index.d.ts +43 -0
  97. package/vendor/components/ColorField/index.d.ts.map +1 -0
  98. package/vendor/components/ColorField/index.js +81 -0
  99. package/vendor/components/ColorField/index.js.map +1 -0
  100. package/vendor/components/ColorPicker/colorPickerTab.d.ts +4 -0
  101. package/vendor/components/ColorPicker/colorPickerTab.d.ts.map +1 -0
  102. package/vendor/components/ColorPicker/colorPickerTab.js +28 -0
  103. package/vendor/components/ColorPicker/colorPickerTab.js.map +1 -0
  104. package/vendor/components/ColorPicker/index.d.ts +59 -0
  105. package/vendor/components/ColorPicker/index.d.ts.map +1 -0
  106. package/vendor/components/ColorPicker/index.js +204 -0
  107. package/vendor/components/ColorPicker/index.js.map +1 -0
  108. package/vendor/components/ColorPicker/themeColors.d.ts +53 -0
  109. package/vendor/components/ColorPicker/themeColors.d.ts.map +1 -0
  110. package/vendor/components/ColorPicker/themeColors.js +110 -0
  111. package/vendor/components/ColorPicker/themeColors.js.map +1 -0
  112. package/vendor/components/Combobox/VirtualizedList.d.ts +1 -1
  113. package/vendor/components/Combobox/VirtualizedList.d.ts.map +1 -1
  114. package/vendor/components/Combobox/VirtualizedList.js.map +1 -1
  115. package/vendor/components/Combobox/index.d.ts +1 -1
  116. package/vendor/components/Combobox/index.d.ts.map +1 -1
  117. package/vendor/components/Combobox/index.js.map +1 -1
  118. package/vendor/components/NumberInput/index.d.ts +51 -0
  119. package/vendor/components/NumberInput/index.d.ts.map +1 -0
  120. package/vendor/components/NumberInput/index.js +82 -0
  121. package/vendor/components/NumberInput/index.js.map +1 -0
  122. package/vendor/components/index.css +280 -24
  123. package/vendor/components/index.d.ts +6 -0
  124. package/vendor/components/index.d.ts.map +1 -1
  125. package/vendor/components/index.js +3 -0
  126. package/vendor/components/index.js.map +1 -1
  127. package/vendor/components/ui/combobox.d.ts.map +1 -1
  128. package/vendor/components/ui/combobox.js +1 -1
  129. package/vendor/components/ui/combobox.js.map +1 -1
  130. package/vendor/components/ui/input-group.d.ts.map +1 -1
  131. package/vendor/components/ui/input-group.js +5 -4
  132. package/vendor/components/ui/input-group.js.map +1 -1
  133. package/src/components/ColorPicker/ColorPicker.d.ts +0 -12
  134. package/src/components/ColorPicker/ColorPicker.js +0 -48
  135. package/src/components/ColorPicker/OptionalColorPicker.d.ts +0 -12
  136. package/src/components/ColorPicker/OptionalColorPicker.js +0 -13
  137. package/src/components/ColorPicker/index.d.ts +0 -2
  138. package/src/components/ColorPicker/index.js +0 -2
@@ -1,12 +1,22 @@
1
1
  import { AG_GRID_VERSION } from './agGrid/AgGridModulesAdapter';
2
2
  import { ADAPTABLE_VERSION } from './EnvVars';
3
- import Emitter from './Utilities/Emitter';
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
- acc[key] = json === undefined ? String(value) : JSON.parse(json);
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
- function ensureDevToolsReady() {
70
- if (DEV_TOOLS_READY) {
71
- return Promise.resolve();
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
- DEV_TOOLS_READY = true;
74
- console.log('Adaptable DevTools is listening for messages!');
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 channelParts = channel.split(':');
78
- const [channelBase, adaptableId] = channelParts;
79
- if (!['Adaptable', 'LayoutManager'].includes(channelBase)) {
151
+ const parsed = parseLogChannel(channel);
152
+ if (!parsed) {
80
153
  return;
81
154
  }
82
- if (channelBase === 'LayoutManager' && adaptableId === 'Diffing') {
83
- return;
84
- }
85
- if (!adaptableId) {
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: channelParts.find((part) => LOG_LEVELS.includes(part)) ?? 'info',
174
+ level: parsed.level,
97
175
  timestamp,
98
- args: args.map((arg) => serializeForPostMessage(formatLogArgForPostMessage(arg))),
176
+ args: formattedArgs.map((arg) => serializeForPostMessage(arg)),
99
177
  },
100
178
  });
101
179
  });
102
- return __ADAPTABLE_DEVTOOLS_EMITTER.emit('ready');
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
- const instance = REGISTERED_ADAPTABLE_INSTANCES.get(adaptableId);
111
- if (instance?.isDestroyed) {
112
- console.warn(`Adaptable DevTools: instance "${adaptableId}" is destroyed; cannot open settings panel`);
113
- return;
201
+ try {
202
+ openSettingsPanel(adaptableId, moduleName);
114
203
  }
115
- const api = instance?.api ?? REGISTERED_ADAPTABLE_APIS.get(adaptableId);
116
- const settingsPanelApi = api?.settingsPanelApi;
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
- function applyThemeToDocumentElement(payload) {
124
- const style = document.documentElement.style;
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
- document.documentElement.style.setProperty(name, String(value ?? ''));
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
- applyThemeToDocumentElement(payload);
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 = REGISTERED_ADAPTABLE_APIS.get(adaptableId);
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
- const api = REGISTERED_ADAPTABLE_APIS.get(adaptableId);
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 !== 'undefined' && !DEV_TOOLS_LISTENING_STARTED) {
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
- void ensureDevToolsReady();
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
- __ADAPTABLE_DEVTOOLS_EMITTER.onIncludeFiredOnce('ready').then(() => {
210
- const { api, adaptableOptions } = adaptableInstance;
211
- if (!api || !adaptableOptions) {
212
- console.error('Cannot register Adaptable instance in DevTools because it is not ready', adaptableInstance);
213
- return;
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
- licenseKey: api.optionsApi.getAdaptableOptions().licenseKey,
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 ?? REGISTERED_ADAPTABLE_APIS.get(adaptableId);
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(state),
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
- window.postMessage(buildMessageForExtension({ type: 'unmount', adaptableId }));
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 publishStateSnapshot(adaptableId) {
355
- const api = REGISTERED_ADAPTABLE_APIS.get(adaptableId);
356
- if (!api) {
357
- return;
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, options, adaptableInstance) {
362
- const { api } = options;
849
+ function registerAdaptableInstanceInDevTools(adaptableId, api, adaptableInstance) {
363
850
  detachAdaptableInstanceListeners(adaptableId);
364
- console.log(`Registering instance "${adaptableId}" into Adaptable DevTools`);
365
- REGISTERED_ADAPTABLE_IDS.add(adaptableId);
366
- REGISTERED_ADAPTABLE_APIS.set(adaptableId, api);
367
- if (adaptableInstance) {
368
- REGISTERED_ADAPTABLE_INSTANCES.set(adaptableId, adaptableInstance);
369
- }
851
+ const registration = {
852
+ api,
853
+ instance: adaptableInstance,
854
+ actions: [],
855
+ unsubscribe: () => { },
856
+ };
370
857
  const onStateChange = (info) => {
371
- postStateChangeMessage(adaptableId, { actionName: info.actionName, api });
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
- postStateChangeMessage(adaptableId, {
375
- actionName: 'AdaptableStateReloaded',
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 adaptableGrid = adaptableInstance ?? REGISTERED_ADAPTABLE_INSTANCES.get(adaptableId);
388
- const unsubscribeFiltersApplied = adaptableGrid?._on('AdapTableFiltersApplied', () => {
880
+ const unsubscribeFiltersApplied = adaptableInstance._on('AdapTableFiltersApplied', () => {
389
881
  cancelScheduledGridRuntimeUpdate(adaptableId);
390
882
  postGridRuntimeUpdate(adaptableId, api);
391
883
  });
392
- INSTANCE_REGISTRATIONS.set(adaptableId, {
393
- api,
394
- unsubscribe: () => {
395
- unsubscribeStateChanged();
396
- unsubscribeStateReloaded();
397
- unsubscribeRowSelectionChanged();
398
- unsubscribeFiltersApplied?.();
399
- unsubscribeDestroy();
400
- },
401
- });
402
- postMountMessage(adaptableId, api);
403
- publishStateSnapshot(adaptableId);
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
  }