@deephaven/dashboard 0.5.2-beta.0 → 0.6.1-demo.8

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 (43) hide show
  1. package/dist/Dashboard.d.ts +2 -1
  2. package/dist/Dashboard.d.ts.map +1 -1
  3. package/dist/Dashboard.js +37 -61
  4. package/dist/Dashboard.js.map +1 -1
  5. package/dist/DashboardLayout.d.ts +3 -1
  6. package/dist/DashboardLayout.d.ts.map +1 -1
  7. package/dist/DashboardLayout.js +57 -93
  8. package/dist/DashboardLayout.js.map +1 -1
  9. package/dist/DashboardUtils.js +16 -9
  10. package/dist/DashboardUtils.js.map +1 -1
  11. package/dist/PanelErrorBoundary.js +41 -73
  12. package/dist/PanelErrorBoundary.js.map +1 -1
  13. package/dist/PanelManager.js +216 -259
  14. package/dist/PanelManager.js.map +1 -1
  15. package/dist/PanelPlaceholder.js +3 -3
  16. package/dist/PanelPlaceholder.js.map +1 -1
  17. package/dist/index.js +13 -13
  18. package/dist/index.js.map +1 -1
  19. package/dist/layout/GLPropTypes.js +3 -3
  20. package/dist/layout/GLPropTypes.js.map +1 -1
  21. package/dist/layout/GoldenLayoutThemeExport.js.map +1 -1
  22. package/dist/layout/LayoutUtils.d.ts +8 -1
  23. package/dist/layout/LayoutUtils.d.ts.map +1 -1
  24. package/dist/layout/LayoutUtils.js +632 -677
  25. package/dist/layout/LayoutUtils.js.map +1 -1
  26. package/dist/layout/golden-layout.js +2 -2
  27. package/dist/layout/golden-layout.js.map +1 -1
  28. package/dist/layout/hooks.js +7 -9
  29. package/dist/layout/hooks.js.map +1 -1
  30. package/dist/layout/index.js +4 -4
  31. package/dist/layout/index.js.map +1 -1
  32. package/dist/redux/actions.js +8 -14
  33. package/dist/redux/actions.js.map +1 -1
  34. package/dist/redux/index.js +6 -21
  35. package/dist/redux/index.js.map +1 -1
  36. package/dist/redux/reducers/dashboardData.js +1 -1
  37. package/dist/redux/reducers/dashboardData.js.map +1 -1
  38. package/dist/redux/reducers/index.js +2 -2
  39. package/dist/redux/reducers/index.js.map +1 -1
  40. package/dist/redux/selectors.js +4 -6
  41. package/dist/redux/selectors.js.map +1 -1
  42. package/dist/tsconfig.tsbuildinfo +1 -1
  43. package/package.json +19 -24
@@ -2,800 +2,755 @@ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (O
2
2
 
3
3
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
4
4
 
5
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
6
-
7
- function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
8
-
9
- function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
10
-
11
5
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
12
6
 
13
7
  import deepEqual from 'deep-equal';
14
8
  import shortid from 'shortid';
9
+ import isMatch from 'lodash.ismatch';
15
10
  import Log from '@deephaven/log';
16
- import GoldenLayoutThemeExport from './GoldenLayoutThemeExport';
11
+ import GoldenLayoutThemeExport from "./GoldenLayoutThemeExport.js";
17
12
  var log = Log.module('LayoutUtils');
18
13
 
19
- var LayoutUtils = /*#__PURE__*/function () {
20
- function LayoutUtils() {
21
- _classCallCheck(this, LayoutUtils);
14
+ class LayoutUtils {
15
+ static activateTab(root, config) {
16
+ var stack = LayoutUtils.getStackForRoot(root, config, false);
17
+
18
+ if (!stack) {
19
+ log.error('Could not find stack for config', config);
20
+ return;
21
+ } // Find the tab with the specified table and activate it
22
+
23
+
24
+ var contentItem = LayoutUtils.getContentItemInStack(stack, config);
25
+ stack.setActiveContentItem(contentItem);
22
26
  }
27
+ /**
28
+ * Is the tab with the given config active
29
+ * @param {ContentItem} root A GoldenLayout content item with the tab
30
+ * @param {Object} config Tab config to match
31
+ * @returns {boolean} True if the tab is active
32
+ */
23
33
 
24
- _createClass(LayoutUtils, null, [{
25
- key: "activateTab",
26
- value: function activateTab(root, config) {
27
- var stack = LayoutUtils.getStackForRoot(root, config, false);
28
34
 
29
- if (!stack) {
30
- log.error('Could not find stack for config', config);
31
- return;
32
- } // Find the tab with the specified table and activate it
33
-
34
-
35
- var contentItem = LayoutUtils.getContentItemInStack(stack, config);
36
- stack.setActiveContentItem(contentItem);
37
- }
38
- /**
39
- * Is the tab with the given config active
40
- * @param {ContentItem} root A GoldenLayout content item with the tab
41
- * @param {Object} config Tab config to match
42
- * @returns {boolean} True if the tab is active
43
- */
44
-
45
- }, {
46
- key: "isActiveTab",
47
- value: function isActiveTab(root, config) {
48
- var stack = LayoutUtils.getStackForRoot(root, config, false);
49
-
50
- if (!stack) {
51
- log.error('Could not find stack for config', config);
52
- return false;
53
- } // Find the item with the specified config and compare with active item
54
-
55
-
56
- var contentItem = LayoutUtils.getContentItemInStack(stack, config);
57
- var activeItem = stack.getActiveContentItem();
58
- return activeItem === contentItem;
59
- }
60
- /**
61
- * Adds a stack to the root layout specified. Adds to the first row/column with only one item
62
- * @param {ContentItem} root A GoldenLayout content item to add the stack to
63
- * @returns The newly created stack.
64
- */
65
-
66
- }, {
67
- key: "addStack",
68
- value: function addStack(parent) {
69
- var columnPreferred = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
70
- var type = columnPreferred ? 'column' : 'row';
71
-
72
- if (parent.isRoot) {
73
- if (!parent.contentItems || parent.contentItems.length === 0) {
74
- parent.addChild({
75
- type: type
76
- });
77
- }
35
+ static isActiveTab(root, config) {
36
+ var stack = LayoutUtils.getStackForRoot(root, config, false);
78
37
 
79
- var child = parent.contentItems[0];
38
+ if (!stack) {
39
+ log.error('Could not find stack for config', config);
40
+ return false;
41
+ } // Find the item with the specified config and compare with active item
80
42
 
81
- var _isCorrectType = columnPreferred ? child.isColumn : child.isRow;
82
43
 
83
- if (!_isCorrectType) {
84
- parent.removeChild(child, true);
85
- parent.addChild({
86
- type: type
87
- });
88
- parent.contentItems[0].addChild(child);
89
- }
44
+ var contentItem = LayoutUtils.getContentItemInStack(stack, config);
45
+ var activeItem = stack.getActiveContentItem();
46
+ return activeItem === contentItem;
47
+ }
48
+ /**
49
+ * Adds a stack to the root layout specified. Adds to the first row/column with only one item
50
+ * @param {ContentItem} root A GoldenLayout content item to add the stack to
51
+ * @returns The newly created stack.
52
+ */
90
53
 
91
- return this.addStack(parent.contentItems[0], columnPreferred);
92
- }
93
54
 
94
- if (parent.contentItems.length < 2) {
55
+ static addStack(parent) {
56
+ var columnPreferred = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
57
+ var type = columnPreferred ? 'column' : 'row';
58
+
59
+ if (parent.isRoot) {
60
+ if (!parent.contentItems || parent.contentItems.length === 0) {
95
61
  parent.addChild({
96
- type: 'stack'
62
+ type
97
63
  });
98
- return parent.contentItems[parent.contentItems.length - 1];
99
64
  }
100
65
 
101
- var newParent = parent.contentItems[parent.contentItems.length - 1];
102
- var isCorrectType = !columnPreferred ? newParent.isColumn : newParent.isRow;
66
+ var child = parent.contentItems[0];
67
+
68
+ var _isCorrectType = columnPreferred ? child.isColumn : child.isRow;
103
69
 
104
- if (!isCorrectType) {
70
+ if (!_isCorrectType) {
71
+ parent.removeChild(child, true);
105
72
  parent.addChild({
106
- type: !columnPreferred ? 'column' : 'row'
107
- });
108
- parent.removeChild(newParent, true);
109
- parent.contentItems[parent.contentItems.length - 1].addChild(newParent);
110
- newParent = parent.contentItems[parent.contentItems.length - 1];
73
+ type
74
+ }); // The addChild may cause the element that has focus to be removed from the DOM, which changes focus to the body
75
+ // Try and maintain the focus as best we can. The unfocused element may still send a blur/focus event so that needs to be handled correctly.
76
+
77
+ var maintainFocusElement = document.activeElement;
78
+ parent.contentItems[0].addChild(child);
79
+ maintainFocusElement === null || maintainFocusElement === void 0 ? void 0 : maintainFocusElement.focus();
111
80
  }
112
81
 
113
- return this.addStack(newParent, !columnPreferred);
82
+ return this.addStack(parent.contentItems[0], columnPreferred);
114
83
  }
115
- /**
116
- * @param {ContentItem} item Golden layout content item to search for the stack
117
- * @param {Config} config The item properties to match
118
- */
119
84
 
120
- }, {
121
- key: "getStackForConfig",
122
- value: function getStackForConfig(item) {
123
- var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
124
- var allowEmptyStack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
85
+ if (parent.contentItems.length < 2) {
86
+ parent.addChild({
87
+ type: 'stack'
88
+ });
89
+ return parent.contentItems[parent.contentItems.length - 1];
90
+ }
125
91
 
126
- if (allowEmptyStack && item.isStack && item.contentItems.length === 0) {
127
- return item;
128
- }
92
+ var newParent = parent.contentItems[parent.contentItems.length - 1];
93
+ var isCorrectType = !columnPreferred ? newParent.isColumn : newParent.isRow;
129
94
 
130
- if (!item.contentItems) {
131
- return null;
132
- }
95
+ if (!isCorrectType) {
96
+ parent.addChild({
97
+ type: !columnPreferred ? 'column' : 'row'
98
+ });
99
+ parent.removeChild(newParent, true);
100
+ parent.contentItems[parent.contentItems.length - 1].addChild(newParent);
101
+ newParent = parent.contentItems[parent.contentItems.length - 1];
102
+ }
133
103
 
134
- for (var i = 0; i < item.contentItems.length; i += 1) {
135
- var contentItem = item.contentItems[i];
104
+ return this.addStack(newParent, !columnPreferred);
105
+ }
106
+ /**
107
+ * Gets the first stack which contains a contentItem with the given config values
108
+ * @param {ContentItem} item Golden layout content item to search for the stack
109
+ * @param {Config} config The item properties to match
110
+ */
136
111
 
137
- if (contentItem.isComponent && contentItem.config) {
138
- var isMatch = true;
139
- var keys = Object.keys(config);
140
112
 
141
- for (var k = 0; k < keys.length; k += 1) {
142
- var key = keys[k];
113
+ static getStackForConfig(item) {
114
+ var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
115
+ var allowEmptyStack = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
143
116
 
144
- if (config[key] !== contentItem.config[key]) {
145
- isMatch = false;
146
- break;
147
- }
148
- }
117
+ if (allowEmptyStack && item.isStack && item.contentItems.length === 0) {
118
+ return item;
119
+ }
149
120
 
150
- if (isMatch) {
151
- return item;
152
- }
153
- }
121
+ if (!item.contentItems) {
122
+ return null;
123
+ }
154
124
 
155
- var stack = this.getStackForConfig(contentItem, config, allowEmptyStack);
125
+ for (var i = 0; i < item.contentItems.length; i += 1) {
126
+ var contentItem = item.contentItems[i];
156
127
 
157
- if (stack) {
158
- return stack;
128
+ if (contentItem.isComponent && contentItem.config) {
129
+ if (isMatch(contentItem.config, config)) {
130
+ return item;
159
131
  }
160
132
  }
161
133
 
162
- return null;
163
- }
164
- /**
165
- * Gets a stack matching the specified config
166
- * @param {Config} config The item config type to match, eg. { component: 'IrisGridPanel', title: 'Table Name' }
167
- * @param {boolean} createIfNecessary Whether to create the stack if it does not exist.
168
- * @param {boolean} matchComponentType If the config doesn't match exactly, just find another one of the same component type
169
- * @param {boolean} allowEmptyStack If no configs match, search for an empty stack that can be used
170
- */
171
-
172
- }, {
173
- key: "getStackForRoot",
174
- value: function getStackForRoot(root, config) {
175
- var createIfNecessary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
176
- var matchComponentType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
177
- var allowEmptyStack = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
178
- var stack = this.getStackForConfig(root, config);
179
-
180
- if (!stack && matchComponentType) {
181
- stack = this.getStackForConfig(root, {
182
- component: config.component
183
- }, allowEmptyStack);
184
- }
185
-
186
- if (!stack && createIfNecessary) {
187
- stack = this.addStack(root);
188
- }
134
+ var stack = this.getStackForConfig(contentItem, config, allowEmptyStack);
189
135
 
190
- return stack;
191
- }
192
- /**
193
- * Gets a stack matching one of the specified types, creates new stack if necessary
194
- * @param {ContentItem} root The GoldenLayout root to find or create the stack in
195
- * @param {Array[string]} types The array of component types to match
196
- * @param {boolean} createIfNecessary Whether to create the stack if it does not exist
197
- * @param {boolean} matchComponentType If the config doesn't match exactly, just find another one of the same component type
198
- * @param {boolean} allowEmptyStack If no configs match, search for an empty stack that can be used
199
- */
200
-
201
- }, {
202
- key: "getStackForComponentTypes",
203
- value: function getStackForComponentTypes(root, types) {
204
- var createIfNecessary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
205
- var matchComponentType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
206
- var allowEmptyStack = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
207
-
208
- for (var i = 0; i < types.length; i += 1) {
209
- var component = types[i];
210
- var isLastType = i === types.length - 1;
211
- var stack = LayoutUtils.getStackForRoot(root, {
212
- component: component
213
- }, createIfNecessary && isLastType, matchComponentType, allowEmptyStack);
214
-
215
- if (stack) {
216
- return stack;
217
- }
136
+ if (stack) {
137
+ return stack;
218
138
  }
139
+ }
219
140
 
220
- return null;
141
+ return null;
142
+ }
143
+ /**
144
+ * Gets a stack matching the specified config
145
+ * @param {Config} config The item config type to match, eg. { component: 'IrisGridPanel', title: 'Table Name' }
146
+ * @param {boolean} createIfNecessary Whether to create the stack if it does not exist.
147
+ * @param {boolean} matchComponentType If the config doesn't match exactly, just find another one of the same component type
148
+ * @param {boolean} allowEmptyStack If no configs match, search for an empty stack that can be used
149
+ */
150
+
151
+
152
+ static getStackForRoot(root, config) {
153
+ var createIfNecessary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
154
+ var matchComponentType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
155
+ var allowEmptyStack = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
156
+ var stack = this.getStackForConfig(root, config);
157
+
158
+ if (!stack && matchComponentType) {
159
+ stack = this.getStackForConfig(root, {
160
+ component: config.component
161
+ }, allowEmptyStack);
221
162
  }
222
- /**
223
- * Gets content item with the specified config in stack.
224
- * @param {ContentItem} stack The stack to search for the item
225
- * @param {Config} config The item config type to match, eg. { component: 'IrisGridPanel', title: 'Table Name' }
226
- * @returns {ContentItem} Returns the found content item, null if not found.
227
- */
228
-
229
- }, {
230
- key: "getContentItemInStack",
231
- value: function getContentItemInStack(stack, config) {
232
- for (var i = 0; i < stack.contentItems.length; i += 1) {
233
- var contentItem = stack.contentItems[i];
234
-
235
- if (contentItem.isComponent && contentItem.config) {
236
- var isMatch = true;
237
- var keys = Object.keys(config);
238
-
239
- for (var k = 0; k < keys.length; k += 1) {
240
- var key = keys[k];
241
-
242
- if (config[key] !== contentItem.config[key]) {
243
- isMatch = false;
244
- break;
245
- }
246
- }
247
-
248
- if (isMatch) {
249
- return contentItem;
250
- }
251
- }
252
- }
253
163
 
254
- return null;
164
+ if (!stack && createIfNecessary) {
165
+ stack = this.addStack(root);
255
166
  }
256
- /**
257
- * Removes dynamic props from components in the given config so this config could be serialized
258
- * @param {Array} config Config object
259
- * @param {(name: string, config: PanelConfig) => PanelConfig | null}
260
- * @returns {Array} Dehydrated config
261
- */
262
-
263
- }, {
264
- key: "dehydrateLayoutConfig",
265
- value: function dehydrateLayoutConfig(config, dehydrateComponent) {
266
- if (!config || !config.length) {
267
- return [];
268
- }
269
167
 
270
- var dehydratedConfig = [];
168
+ return stack;
169
+ }
170
+ /**
171
+ * Gets a stack matching one of the specified types, creates new stack if necessary
172
+ * @param {ContentItem} root The GoldenLayout root to find or create the stack in
173
+ * @param {Array[string]} types The array of component types to match
174
+ * @param {boolean} createIfNecessary Whether to create the stack if it does not exist
175
+ * @param {boolean} matchComponentType If the config doesn't match exactly, just find another one of the same component type
176
+ * @param {boolean} allowEmptyStack If no configs match, search for an empty stack that can be used
177
+ */
178
+
179
+
180
+ static getStackForComponentTypes(root, types) {
181
+ var createIfNecessary = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
182
+ var matchComponentType = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
183
+ var allowEmptyStack = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
184
+
185
+ for (var i = 0; i < types.length; i += 1) {
186
+ var component = types[i];
187
+ var isLastType = i === types.length - 1;
188
+ var stack = LayoutUtils.getStackForRoot(root, {
189
+ component
190
+ }, createIfNecessary && isLastType, matchComponentType, allowEmptyStack);
191
+
192
+ if (stack) {
193
+ return stack;
194
+ }
195
+ }
271
196
 
272
- for (var i = 0; i < config.length; i += 1) {
273
- var itemConfig = config[i];
274
- var component = itemConfig.component,
275
- content = itemConfig.content;
197
+ return null;
198
+ }
199
+ /**
200
+ * Gets first content item with the specified config in stack.
201
+ * @param {ContentItem} stack The stack to search for the item
202
+ * @param {Config} config The item config type to match, eg. { component: 'IrisGridPanel', title: 'Table Name' }
203
+ * @returns {ContentItem} Returns the found content item, null if not found.
204
+ */
276
205
 
277
- if (component) {
278
- var dehydratedComponent = dehydrateComponent(component, itemConfig);
279
206
 
280
- if (dehydratedComponent) {
281
- dehydratedConfig.push(dehydratedComponent);
282
- } else {
283
- log.debug2("dehydrateLayoutConfig: skipping unmapped component \"".concat(component, "\""));
284
- }
285
- } else if (content) {
286
- var layoutItemConfig = _objectSpread(_objectSpread({}, itemConfig), {}, {
287
- content: LayoutUtils.dehydrateLayoutConfig(content, dehydrateComponent)
288
- });
207
+ static getContentItemInStack(stack, config) {
208
+ for (var i = 0; i < stack.contentItems.length; i += 1) {
209
+ var contentItem = stack.contentItems[i];
289
210
 
290
- dehydratedConfig.push(layoutItemConfig);
291
- } else {
292
- dehydratedConfig.push(itemConfig);
211
+ if (contentItem.isComponent && contentItem.config) {
212
+ if (isMatch(contentItem.config, config)) {
213
+ return contentItem;
293
214
  }
294
215
  }
216
+ }
295
217
 
296
- return dehydratedConfig;
218
+ return null;
219
+ }
220
+ /**
221
+ * Removes dynamic props from components in the given config so this config could be serialized
222
+ * @param {Array} config Config object
223
+ * @param {(name: string, config: PanelConfig) => PanelConfig | null}
224
+ * @returns {Array} Dehydrated config
225
+ */
226
+
227
+
228
+ static dehydrateLayoutConfig(config, dehydrateComponent) {
229
+ if (!config || !config.length) {
230
+ return [];
297
231
  }
298
- }, {
299
- key: "getTabPoint",
300
- value: function getTabPoint(glContainer) {
301
- var tab = glContainer.tab;
302
232
 
303
- if (tab == null) {
304
- throw new Error('Cannot get tab for panel container', glContainer);
305
- }
233
+ var dehydratedConfig = [];
234
+
235
+ for (var i = 0; i < config.length; i += 1) {
236
+ var itemConfig = config[i];
237
+ var {
238
+ component,
239
+ content
240
+ } = itemConfig;
241
+
242
+ if (component) {
243
+ var dehydratedComponent = dehydrateComponent(component, itemConfig);
306
244
 
307
- var tabRect = tab.element[0].getBoundingClientRect();
308
- return [tabRect.left + tabRect.width * 0.5, tabRect.bottom - 8];
309
- }
310
- /**
311
- * Drop minor changes in Layout Configuration for deep comparison
312
- * @param {Object} config Layout Configuration
313
- *
314
- * minor changes:
315
- * 1. sorts in grid
316
- * 2. quick filters in grid
317
- * 3. active item
318
- *
319
- * item id is also removed
320
- */
321
-
322
- }, {
323
- key: "dropLayoutMinorChange",
324
- value: function dropLayoutMinorChange(config) {
325
- for (var i = 0; i < config.length; i += 1) {
326
- var itemConfig = config[i];
327
- var component = itemConfig.component,
328
- content = itemConfig.content,
329
- activeItemIndex = itemConfig.activeItemIndex;
330
-
331
- if (content) {
332
- if (activeItemIndex || activeItemIndex === 0) {
333
- delete itemConfig.activeItemIndex;
334
- }
335
-
336
- LayoutUtils.dropLayoutMinorChange(content);
337
- } else if (component === 'IrisGridPanel') {
338
- if (itemConfig.props.panelState) {
339
- delete itemConfig.id;
340
- itemConfig.props.panelState.irisGridState.sorts = [];
341
- itemConfig.props.panelState.irisGridState.quickFilters = [];
342
- }
245
+ if (dehydratedComponent) {
246
+ dehydratedConfig.push(dehydratedComponent);
247
+ } else {
248
+ log.debug2("dehydrateLayoutConfig: skipping unmapped component \"".concat(component, "\""));
343
249
  }
250
+ } else if (content) {
251
+ var layoutItemConfig = _objectSpread(_objectSpread({}, itemConfig), {}, {
252
+ content: LayoutUtils.dehydrateLayoutConfig(content, dehydrateComponent)
253
+ });
254
+
255
+ dehydratedConfig.push(layoutItemConfig);
256
+ } else {
257
+ dehydratedConfig.push(itemConfig);
344
258
  }
345
259
  }
346
- /**
347
- * Compare two layouts to see if they are equivalent
348
- * @param {object} layout1 A Golden Layout config object
349
- * @param {object} layout2 Another Golden layout config object
350
- * @param {boolean} major When true, will ignore "minor" property differences (eg. sorts)
351
- */
352
-
353
- }, {
354
- key: "isEqual",
355
- value: function isEqual(layout1, layout2) {
356
- var major = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
357
-
358
- if (major) {
359
- var layout1Clone = LayoutUtils.cloneLayout(layout1);
360
- var layout2Clone = LayoutUtils.cloneLayout(layout2);
361
- LayoutUtils.dropLayoutMinorChange(layout1Clone);
362
- LayoutUtils.dropLayoutMinorChange(layout2Clone);
363
- return deepEqual(layout1Clone, layout2Clone);
364
- }
365
260
 
366
- return deepEqual(layout1, layout2);
367
- }
368
- }, {
369
- key: "cloneLayout",
370
- value: function cloneLayout(layout) {
371
- return JSON.parse(JSON.stringify(layout));
372
- }
373
- /**
374
- * Adds dynamic props to components in the given config so this config could be used to initialize a layout
375
- * @param {GoldenLayout.Config} config Dehydrated config object
376
- * @param {(name: string, config: PanelProps) => PanelProps} hydrateComponent Function to hydrate the component
377
- * @returns {Array} Hydrated config
378
- */
379
-
380
- }, {
381
- key: "hydrateLayoutConfig",
382
- value: function hydrateLayoutConfig(config, hydrateComponent) {
383
- if (!config || !config.length) {
384
- return [];
385
- }
261
+ return dehydratedConfig;
262
+ }
386
263
 
387
- var hydratedConfig = [];
388
-
389
- for (var i = 0; i < config.length; i += 1) {
390
- var itemConfig = config[i];
391
- var component = itemConfig.component,
392
- content = itemConfig.content,
393
- props = itemConfig.props,
394
- type = itemConfig.type;
395
-
396
- if (type === 'react-component') {
397
- var _itemConfig$id;
398
-
399
- hydratedConfig.push(_objectSpread(_objectSpread({}, itemConfig), {}, {
400
- id: (_itemConfig$id = itemConfig === null || itemConfig === void 0 ? void 0 : itemConfig.id) !== null && _itemConfig$id !== void 0 ? _itemConfig$id : shortid(),
401
- props: hydrateComponent(component, props)
402
- }));
403
- } else if (content) {
404
- var contentConfig = LayoutUtils.hydrateLayoutConfig(content, hydrateComponent);
405
-
406
- if (itemConfig.activeItemIndex != null && itemConfig.activeItemIndex >= contentConfig.length) {
407
- log.warn('Fixing bad activeItemIndex!', itemConfig.activeItemIndex, itemConfig);
408
- itemConfig.activeItemIndex = 0;
409
- }
410
-
411
- hydratedConfig.push(_objectSpread(_objectSpread({}, itemConfig), {}, {
412
- content: contentConfig
413
- }));
414
- } else {
415
- hydratedConfig.push(itemConfig);
264
+ static getTabPoint(glContainer) {
265
+ var {
266
+ tab
267
+ } = glContainer;
268
+
269
+ if (tab == null) {
270
+ throw new Error('Cannot get tab for panel container', glContainer);
271
+ }
272
+
273
+ var tabRect = tab.element[0].getBoundingClientRect();
274
+ return [tabRect.left + tabRect.width * 0.5, tabRect.bottom - 8];
275
+ }
276
+ /**
277
+ * Drop minor changes in Layout Configuration for deep comparison
278
+ * @param {Object} config Layout Configuration
279
+ *
280
+ * minor changes:
281
+ * 1. sorts in grid
282
+ * 2. quick filters in grid
283
+ * 3. active item
284
+ *
285
+ * item id is also removed
286
+ */
287
+
288
+
289
+ static dropLayoutMinorChange(config) {
290
+ for (var i = 0; i < config.length; i += 1) {
291
+ var itemConfig = config[i];
292
+ var {
293
+ component,
294
+ content,
295
+ activeItemIndex
296
+ } = itemConfig;
297
+
298
+ if (content) {
299
+ if (activeItemIndex || activeItemIndex === 0) {
300
+ delete itemConfig.activeItemIndex;
416
301
  }
417
- }
418
302
 
419
- return hydratedConfig;
420
- }
421
- /**
422
- * Opens a component. It will try and open the component in an existing stack of the same component.
423
- * If `replaceExisting` is true and there is a component found with the same `config.id`, it will replace that component with this one.
424
- * If `allowStack` is true and there is a component of the same type found, it will open in that stack (potentially covering up a panel).
425
- * @param {ContentItem} root The GoldenLayout root to open the component in
426
- * @param {Config} config The component config definition to open
427
- * @param {Boolean} replaceExisting Whether it should replace the existing one matching component type and id, or open a new one
428
- * @param {Config} replaceConfig The component config to replace
429
- * @param {Boolean} createNewStack True to force opening in a new stack, false to try and open in a stack with the same type of component.
430
- * @param {String} focusElement The element to focus on
431
- * @param {MouseEvent} dragEvent Whether component is being created with a drag, mouse event is initial position for drag proxy
432
- */
433
-
434
- }, {
435
- key: "openComponent",
436
- value: function openComponent() {
437
- var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
438
- root = _ref.root,
439
- configParam = _ref.config,
440
- _ref$replaceExisting = _ref.replaceExisting,
441
- replaceExisting = _ref$replaceExisting === void 0 ? true : _ref$replaceExisting,
442
- _ref$replaceConfig = _ref.replaceConfig,
443
- replaceConfig = _ref$replaceConfig === void 0 ? null : _ref$replaceConfig,
444
- _ref$createNewStack = _ref.createNewStack,
445
- createNewStack = _ref$createNewStack === void 0 ? false : _ref$createNewStack,
446
- _ref$focusElement = _ref.focusElement,
447
- focusElement = _ref$focusElement === void 0 ? null : _ref$focusElement,
448
- _ref$dragEvent = _ref.dragEvent,
449
- dragEvent = _ref$dragEvent === void 0 ? null : _ref$dragEvent;
450
-
451
- // attempt to retain focus after dom manipulation, which can break focus
452
- var maintainFocusElement = document.activeElement;
453
-
454
- var config = _objectSpread({}, configParam);
455
-
456
- if (!config.id) {
457
- config.id = shortid.generate();
303
+ LayoutUtils.dropLayoutMinorChange(content);
304
+ } else if (component === 'IrisGridPanel') {
305
+ if (itemConfig.props.panelState) {
306
+ delete itemConfig.id;
307
+ itemConfig.props.panelState.irisGridState.sorts = [];
308
+ itemConfig.props.panelState.irisGridState.quickFilters = [];
309
+ }
458
310
  }
311
+ }
312
+ }
313
+ /**
314
+ * Compare two layouts to see if they are equivalent
315
+ * @param {object} layout1 A Golden Layout config object
316
+ * @param {object} layout2 Another Golden layout config object
317
+ * @param {boolean} major When true, will ignore "minor" property differences (eg. sorts)
318
+ */
319
+
320
+
321
+ static isEqual(layout1, layout2) {
322
+ var major = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
323
+
324
+ if (major) {
325
+ var layout1Clone = LayoutUtils.cloneLayout(layout1);
326
+ var layout2Clone = LayoutUtils.cloneLayout(layout2);
327
+ LayoutUtils.dropLayoutMinorChange(layout1Clone);
328
+ LayoutUtils.dropLayoutMinorChange(layout2Clone);
329
+ return deepEqual(layout1Clone, layout2Clone);
330
+ }
459
331
 
460
- if (dragEvent) {
461
- root.layoutManager.createDragSourceFromEvent(config, dragEvent);
462
- return;
463
- }
332
+ return deepEqual(layout1, layout2);
333
+ }
334
+
335
+ static cloneLayout(layout) {
336
+ return JSON.parse(JSON.stringify(layout));
337
+ }
338
+ /**
339
+ * Adds dynamic props to components in the given config so this config could be used to initialize a layout
340
+ * @param {GoldenLayout.Config} config Dehydrated config object
341
+ * @param {(name: string, config: PanelProps) => PanelProps} hydrateComponent Function to hydrate the component
342
+ * @returns {Array} Hydrated config
343
+ */
464
344
 
465
- var searchConfig = replaceConfig || {
466
- id: config.id,
467
- component: config.component
468
- };
469
- var stack = createNewStack ? LayoutUtils.addStack(root) : LayoutUtils.getStackForRoot(root, searchConfig);
470
- var oldContentItem = LayoutUtils.getContentItemInStack(stack, searchConfig);
471
-
472
- if (focusElement) {
473
- // We need to listen for when the stack is created
474
- var onComponentCreated = function onComponentCreated(event) {
475
- log.debug('Component created, focusing element', focusElement);
476
- stack.off('componentCreated', onComponentCreated);
477
- var element = event.origin.element; // Need to wait until the component actually renders.
478
-
479
- requestAnimationFrame(function () {
480
- LayoutUtils.focusElement(element[0], focusElement);
481
- });
482
- };
483
-
484
- stack.on('componentCreated', onComponentCreated);
485
- }
486
345
 
487
- if (replaceExisting && oldContentItem) {
488
- var index = stack.contentItems.indexOf(oldContentItem); // Using remove/add here instead of replaceChild because I was getting errors with replaceChild... should be the same.
489
- // Add first so that the stack doesn't get screwed up
346
+ static hydrateLayoutConfig(config, hydrateComponent) {
347
+ if (!config || !config.length) {
348
+ return [];
349
+ }
350
+
351
+ var hydratedConfig = [];
352
+
353
+ for (var i = 0; i < config.length; i += 1) {
354
+ var itemConfig = config[i];
355
+ var {
356
+ component,
357
+ content,
358
+ props,
359
+ type
360
+ } = itemConfig;
361
+
362
+ if (type === 'react-component') {
363
+ var _itemConfig$id;
364
+
365
+ hydratedConfig.push(_objectSpread(_objectSpread({}, itemConfig), {}, {
366
+ id: (_itemConfig$id = itemConfig === null || itemConfig === void 0 ? void 0 : itemConfig.id) !== null && _itemConfig$id !== void 0 ? _itemConfig$id : shortid(),
367
+ props: hydrateComponent(component, props)
368
+ }));
369
+ } else if (content) {
370
+ var contentConfig = LayoutUtils.hydrateLayoutConfig(content, hydrateComponent);
371
+
372
+ if (itemConfig.activeItemIndex != null && itemConfig.activeItemIndex >= contentConfig.length) {
373
+ log.warn('Fixing bad activeItemIndex!', itemConfig.activeItemIndex, itemConfig);
374
+ itemConfig.activeItemIndex = 0;
375
+ }
490
376
 
491
- stack.addChild(config, index + 1);
492
- stack.removeChild(oldContentItem);
493
- stack.setActiveContentItem(stack.contentItems[index]);
377
+ hydratedConfig.push(_objectSpread(_objectSpread({}, itemConfig), {}, {
378
+ content: contentConfig
379
+ }));
494
380
  } else {
495
- stack.addChild(config);
381
+ hydratedConfig.push(itemConfig);
496
382
  }
383
+ }
497
384
 
498
- if (!focusElement && maintainFocusElement) {
499
- maintainFocusElement.focus();
500
- }
385
+ return hydratedConfig;
386
+ }
387
+ /**
388
+ * Opens a component. It will try and open the component in an existing stack of the same component.
389
+ * If `replaceExisting` is true and there is a component found with the same `config.id`, it will replace that component with this one.
390
+ * If `allowStack` is true and there is a component of the same type found, it will open in that stack (potentially covering up a panel).
391
+ * @param {ContentItem} root The GoldenLayout root to open the component in
392
+ * @param {Config} config The component config definition to open
393
+ * @param {Boolean} replaceExisting Whether it should replace the existing one matching component type and id, or open a new one
394
+ * @param {Config} replaceConfig The component config to replace
395
+ * @param {Boolean} createNewStack True to force opening in a new stack, false to try and open in a stack with the same type of component.
396
+ * @param {String} focusElement The element to focus on
397
+ * @param {MouseEvent} dragEvent Whether component is being created with a drag, mouse event is initial position for drag proxy
398
+ */
399
+
400
+
401
+ static openComponent() {
402
+ var {
403
+ root,
404
+ config: configParam,
405
+ replaceExisting = true,
406
+ replaceConfig = null,
407
+ createNewStack = false,
408
+ focusElement = null,
409
+ dragEvent = null
410
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
411
+ // attempt to retain focus after dom manipulation, which can break focus
412
+ var maintainFocusElement = document.activeElement;
413
+
414
+ var config = _objectSpread({}, configParam);
415
+
416
+ if (!config.id) {
417
+ config.id = shortid.generate();
501
418
  }
502
- /**
503
- * Opens a component in an given stack.
504
- * If `replaceExisting` is true and there is a component found with the same `config.id`, it will replace that component with this one
505
- * @param {ContentItem} stack The GoldenLayout stack to open the component in
506
- * @param {Config} config The component config definition to open
507
- * @param {Boolean} replaceExisting Whether it should replace the existing one matching component type and id, or open a new one
508
- */
509
-
510
- }, {
511
- key: "openComponentInStack",
512
- value: function openComponentInStack(stack, config) {
513
- var replaceExisting = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
514
- var maintainFocusElement = document.activeElement; // attempt to retain focus after dom manipulation, which can break focus
515
-
516
- var searchConfig = {
517
- id: config.id,
518
- component: config.component
419
+
420
+ if (dragEvent) {
421
+ root.layoutManager.createDragSourceFromEvent(config, dragEvent);
422
+ return;
423
+ }
424
+
425
+ var searchConfig = replaceConfig || {
426
+ id: config.id,
427
+ component: config.component
428
+ };
429
+ var stack = createNewStack ? LayoutUtils.addStack(root) : LayoutUtils.getStackForRoot(root, searchConfig);
430
+ var oldContentItem = LayoutUtils.getContentItemInStack(stack, searchConfig);
431
+
432
+ if (focusElement) {
433
+ // We need to listen for when the stack is created
434
+ var onComponentCreated = event => {
435
+ log.debug('Component created, focusing element', focusElement);
436
+ stack.off('componentCreated', onComponentCreated);
437
+ var {
438
+ element
439
+ } = event.origin; // Need to wait until the component actually renders.
440
+
441
+ requestAnimationFrame(() => {
442
+ LayoutUtils.focusElement(element[0], focusElement);
443
+ });
519
444
  };
520
- var oldContentItem = LayoutUtils.getContentItemInStack(stack, searchConfig);
521
445
 
522
- if (replaceExisting && oldContentItem) {
523
- var index = stack.contentItems.indexOf(oldContentItem); // Using remove/add here instead of replaceChild because I was getting errors with replaceChild... should be the same.
524
- // Add first so that the stack doesn't get screwed up
446
+ stack.on('componentCreated', onComponentCreated);
447
+ }
525
448
 
526
- stack.addChild(config, index + 1);
527
- stack.removeChild(oldContentItem);
528
- stack.setActiveContentItem(stack.contentItems[index]);
529
- } else {
530
- stack.addChild(config);
531
- }
449
+ if (replaceExisting && oldContentItem) {
450
+ var index = stack.contentItems.indexOf(oldContentItem); // Using remove/add here instead of replaceChild because I was getting errors with replaceChild... should be the same.
451
+ // Add first so that the stack doesn't get screwed up
532
452
 
533
- if (maintainFocusElement) maintainFocusElement.focus();
453
+ stack.addChild(config, index + 1);
454
+ stack.removeChild(oldContentItem);
455
+ stack.setActiveContentItem(stack.contentItems[index]);
456
+ } else {
457
+ stack.addChild(config);
534
458
  }
535
- /**
536
- * Close the specified component and remove it from the stack it's currently in
537
- * @param {ContentItem} root The GoldenLayout root to search and close the component in
538
- * @param {Config} config The GoldenLayout component config definition to close, eg. { component: 'IrisGridPanel', id: 'table-t' }
539
- */
540
459
 
541
- }, {
542
- key: "closeComponent",
543
- value: function closeComponent(root, config) {
544
- var stack = LayoutUtils.getStackForRoot(root, config, false, false, false);
460
+ if (!focusElement && maintainFocusElement) {
461
+ maintainFocusElement.focus();
462
+ }
463
+ }
464
+ /**
465
+ * Opens a component in an given stack.
466
+ * If `replaceExisting` is true and there is a component found with the same `config.id`, it will replace that component with this one
467
+ * @param {ContentItem} stack The GoldenLayout stack to open the component in
468
+ * @param {Config} config The component config definition to open
469
+ * @param {Boolean} replaceExisting Whether it should replace the existing one matching component type and id, or open a new one
470
+ */
471
+
472
+
473
+ static openComponentInStack(stack, config) {
474
+ var replaceExisting = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
475
+ var maintainFocusElement = document.activeElement; // attempt to retain focus after dom manipulation, which can break focus
476
+
477
+ var searchConfig = {
478
+ id: config.id
479
+ };
480
+ var oldContentItem = LayoutUtils.getContentItemInStack(stack, searchConfig);
481
+
482
+ if (replaceExisting && oldContentItem) {
483
+ var index = stack.contentItems.indexOf(oldContentItem); // Using remove/add here instead of replaceChild because I was getting errors with replaceChild... should be the same.
484
+ // Add first so that the stack doesn't get screwed up
485
+
486
+ stack.addChild(config, index + 1);
487
+ stack.removeChild(oldContentItem);
488
+ stack.setActiveContentItem(stack.contentItems[index]);
489
+ } else {
490
+ stack.addChild(config);
491
+ }
545
492
 
546
- if (!stack) {
547
- log.warn('Cannot find stack for component, ignoring close', config);
548
- return;
549
- } // Find the tab with the specified config and remove it
550
- // Same component was used to get the stack above, so getContentItemInStack shouldn't return null
493
+ if (maintainFocusElement) maintainFocusElement.focus();
494
+ }
495
+ /**
496
+ * Close the specified component and remove it from the stack it's currently in
497
+ * @param {ContentItem} root The GoldenLayout root to search and close the component in
498
+ * @param {Config} config The GoldenLayout component config definition to close, eg. { component: 'IrisGridPanel', id: 'table-t' }
499
+ */
551
500
 
552
501
 
553
- var oldContentItem = LayoutUtils.getContentItemInStack(stack, config);
554
- var maintainFocusElement = document.activeElement; // attempt to retain focus after dom manipulation, which can break focus
502
+ static closeComponent(root, config) {
503
+ var stack = LayoutUtils.getStackForRoot(root, config, false, false, false);
555
504
 
556
- if (oldContentItem.isComponent) {
557
- oldContentItem.container.close();
558
- } else {
559
- stack.removeChild(oldContentItem);
560
- } // if focused element is still in dom restore focus, note it could have been in the removed panel so check first
505
+ if (!stack) {
506
+ log.warn('Cannot find stack for component, ignoring close', config);
507
+ return;
508
+ } // Find the tab with the specified config and remove it
509
+ // Same component was used to get the stack above, so getContentItemInStack shouldn't return null
561
510
 
562
511
 
563
- if (maintainFocusElement && document.contains(maintainFocusElement)) {
564
- maintainFocusElement.focus();
565
- }
566
- }
567
- }, {
568
- key: "renameComponent",
569
- value: function renameComponent(root, config, newTitle) {
570
- var stack = LayoutUtils.getStackForRoot(root, config, false);
512
+ var oldContentItem = LayoutUtils.getContentItemInStack(stack, config);
513
+ var maintainFocusElement = document.activeElement; // attempt to retain focus after dom manipulation, which can break focus
571
514
 
572
- if (!stack) {
573
- log.error('Could not find stack for config', config);
574
- return;
575
- } // Find the tab with the specified config and rename it
515
+ if (oldContentItem.isComponent) {
516
+ oldContentItem.container.close();
517
+ } else {
518
+ stack.removeChild(oldContentItem);
519
+ } // if focused element is still in dom restore focus, note it could have been in the removed panel so check first
576
520
 
577
521
 
578
- var contentItem = LayoutUtils.getContentItemInStack(stack, config);
579
- contentItem.setTitle(newTitle);
522
+ if (maintainFocusElement && document.contains(maintainFocusElement)) {
523
+ maintainFocusElement.focus();
580
524
  }
581
- /**
582
- * Create a component clone based on the given config
583
- * @param {ContentItem} root The GoldenLayout root to clone the component in
584
- * @param {Config} config The config to clone
585
- * @returns {Config} Clone config
586
- */
525
+ }
587
526
 
588
- }, {
589
- key: "cloneComponent",
590
- value: function cloneComponent(root, config) {
591
- var stack = LayoutUtils.getStackForRoot(root, config, false);
527
+ static renameComponent(root, config, newTitle) {
528
+ var stack = LayoutUtils.getStackForRoot(root, config, false);
592
529
 
593
- if (!stack) {
594
- log.error('Could not find stack for config', config);
595
- return null;
596
- }
530
+ if (!stack) {
531
+ log.error('Could not find stack for config', config);
532
+ return;
533
+ } // Find the tab with the specified config and rename it
597
534
 
598
- var _config$props$panelSt = config.props.panelState,
599
- panelState = _config$props$panelSt === void 0 ? null : _config$props$panelSt;
600
- var componentState = config.componentState;
601
535
 
602
- if (componentState) {
603
- panelState = componentState.panelState;
604
- }
536
+ var contentItem = LayoutUtils.getContentItemInStack(stack, config);
537
+ contentItem.setTitle(newTitle);
538
+ }
539
+ /**
540
+ * Create a component clone based on the given config
541
+ * @param {ContentItem} root The GoldenLayout root to clone the component in
542
+ * @param {Config} config The config to clone
543
+ * @returns {Config} Clone config
544
+ */
605
545
 
606
- var cloneConfig = {
607
- type: 'react-component',
608
- component: config.component,
609
- props: _objectSpread(_objectSpread({}, config.props), {}, {
610
- panelState: panelState
611
- }),
612
- title: "".concat(config.title, " Copy"),
613
- id: shortid.generate()
614
- };
615
- LayoutUtils.openComponentInStack(stack, cloneConfig);
616
- return cloneConfig;
617
- }
618
- }, {
619
- key: "makeDefaultLayout",
620
- value: function makeDefaultLayout() {
621
- return {
622
- dimensions: {
623
- headerHeight: GoldenLayoutThemeExport.tabHeight,
624
- borderWidth: GoldenLayoutThemeExport.dragBorderWidth,
625
- borderGrabWidth: 10
626
- },
627
- settings: {
628
- showPopoutIcon: false,
629
- showCloseIcon: false,
630
- constrainDragToContainer: false
631
- }
632
- };
546
+
547
+ static cloneComponent(root, config) {
548
+ var stack = LayoutUtils.getStackForRoot(root, config, false);
549
+
550
+ if (!stack) {
551
+ log.error('Could not find stack for config', config);
552
+ return null;
633
553
  }
634
- /**
635
- * Gets a containers root node
636
- * @param {GlContainer} container The Golden Layout container to get the root for
637
- */
638
554
 
639
- }, {
640
- key: "getRootFromContainer",
641
- value: function getRootFromContainer(container) {
642
- return container.layoutManager.root;
555
+ var panelState = LayoutUtils.getPanelComponentState(config);
556
+ var cloneConfig = {
557
+ type: 'react-component',
558
+ component: config.component,
559
+ props: _objectSpread(_objectSpread({}, config.props), {}, {
560
+ panelState
561
+ }),
562
+ title: "".concat(config.title, " Copy"),
563
+ id: shortid.generate()
564
+ };
565
+ LayoutUtils.openComponentInStack(stack, cloneConfig);
566
+ return cloneConfig;
567
+ }
568
+ /**
569
+ * Get panel component state for the given config
570
+ * @param {Object} config Panel config
571
+ * @returns {Object} Panel state
572
+ */
573
+
574
+
575
+ static getPanelComponentState(config) {
576
+ var _ref, _config$componentStat, _config$componentStat2, _config$props;
577
+
578
+ return (// Fallback to props.panelState for uninitialized panels
579
+ (_ref = (_config$componentStat = (_config$componentStat2 = config.componentState) === null || _config$componentStat2 === void 0 ? void 0 : _config$componentStat2.panelState) !== null && _config$componentStat !== void 0 ? _config$componentStat : (_config$props = config.props) === null || _config$props === void 0 ? void 0 : _config$props.panelState) !== null && _ref !== void 0 ? _ref : null
580
+ );
581
+ }
582
+
583
+ static makeDefaultLayout() {
584
+ return {
585
+ dimensions: {
586
+ headerHeight: GoldenLayoutThemeExport.tabHeight,
587
+ borderWidth: GoldenLayoutThemeExport.dragBorderWidth,
588
+ borderGrabWidth: 10
589
+ },
590
+ settings: {
591
+ showPopoutIcon: false,
592
+ showCloseIcon: false,
593
+ constrainDragToContainer: false
594
+ }
595
+ };
596
+ }
597
+ /**
598
+ * Gets a containers root node
599
+ * @param {GlContainer} container The Golden Layout container to get the root for
600
+ */
601
+
602
+
603
+ static getRootFromContainer(container) {
604
+ return container.layoutManager.root;
605
+ }
606
+ /**
607
+ * Gets the config for the panel component given a glContainer
608
+ * @param {GlContainer} container The Golden Layout container to get the config for
609
+ */
610
+
611
+
612
+ static getComponentConfigFromContainer(container) {
613
+ if (container) {
614
+ if (container.tab && container.tab.contentItem) {
615
+ return container.tab.contentItem.config;
616
+ } // If the container hasn't populated the tab yet, just get the config directly from the container
617
+ // eslint-disable-next-line no-underscore-dangle
618
+
619
+
620
+ return container._config;
643
621
  }
644
- /**
645
- * Gets the config for the panel component given a glContainer
646
- * @param {GlContainer} container The Golden Layout container to get the config for
647
- */
648
622
 
649
- }, {
650
- key: "getComponentConfigFromContainer",
651
- value: function getComponentConfigFromContainer(container) {
652
- if (container) {
653
- if (container.tab && container.tab.contentItem) {
654
- return container.tab.contentItem.config;
655
- } // If the container hasn't populated the tab yet, just get the config directly from the container
656
- // eslint-disable-next-line no-underscore-dangle
623
+ return null;
624
+ }
657
625
 
626
+ static getTitleFromContainer(container) {
627
+ if (container && container.tab && container.tab.contentItem) {
628
+ return container.tab.contentItem.config.title;
629
+ }
658
630
 
659
- return container._config;
660
- }
631
+ return null;
632
+ }
661
633
 
662
- return null;
634
+ static getTitleFromTab(tab) {
635
+ if (tab && tab.contentItem) {
636
+ return tab.contentItem.config.title;
663
637
  }
664
- }, {
665
- key: "getTitleFromContainer",
666
- value: function getTitleFromContainer(container) {
667
- if (container && container.tab && container.tab.contentItem) {
668
- return container.tab.contentItem.config.title;
669
- }
670
638
 
671
- return null;
639
+ return null;
640
+ }
641
+ /**
642
+ * Retrieve the panel ID for the provided golden layout container
643
+ * @param {GlContainer} glContainer The container to get the panel ID for
644
+ * @returns {string|null} Panel ID
645
+ */
646
+
647
+
648
+ static getIdFromContainer(glContainer) {
649
+ var config = LayoutUtils.getComponentConfigFromContainer(glContainer);
650
+
651
+ if (config) {
652
+ return config.id;
672
653
  }
673
- }, {
674
- key: "getTitleFromTab",
675
- value: function getTitleFromTab(tab) {
676
- if (tab && tab.contentItem) {
677
- return tab.contentItem.config.title;
678
- }
679
654
 
680
- return null;
655
+ return null;
656
+ }
657
+ /**
658
+ * Retrieve the ID of the panel provided
659
+ * @param {Component} panel The panel to get the ID for
660
+ * @returns {string|null} Panel ID
661
+ */
662
+
663
+
664
+ static getIdFromPanel(panel) {
665
+ var {
666
+ glContainer
667
+ } = panel.props;
668
+ return LayoutUtils.getIdFromContainer(glContainer);
669
+ }
670
+ /**
671
+ * Get component name from the panel instance
672
+ * @param {Component} panel Panel to get component name for
673
+ * @returns {string} Component name or null if unable to retrieve name
674
+ */
675
+
676
+
677
+ static getComponentNameFromPanel(panel) {
678
+ var _config$component;
679
+
680
+ var {
681
+ glContainer
682
+ } = panel.props;
683
+ var config = LayoutUtils.getComponentConfigFromContainer(glContainer);
684
+ return (_config$component = config === null || config === void 0 ? void 0 : config.component) !== null && _config$component !== void 0 ? _config$component : null;
685
+ }
686
+ /**
687
+ * Get component name for wrapped and un-wrapped components
688
+ * @param {Component} component Component to get name for
689
+ * @returns {string} Component name
690
+ * @throws If displayName for the component is not defined
691
+ */
692
+
693
+
694
+ static getComponentName(component) {
695
+ var _component$WrappedCom, _component$WrappedCom2;
696
+
697
+ var name = (_component$WrappedCom = (_component$WrappedCom2 = component.WrappedComponent) === null || _component$WrappedCom2 === void 0 ? void 0 : _component$WrappedCom2.displayName) !== null && _component$WrappedCom !== void 0 ? _component$WrappedCom : component.displayName;
698
+
699
+ if (name == null) {
700
+ throw new Error('Component displayName not defined', component);
681
701
  }
682
- /**
683
- * Retrieve the panel ID for the provided golden layout container
684
- * @param {GlContainer} glContainer The container to get the panel ID for
685
- * @returns {string|null} Panel ID
686
- */
687
702
 
688
- }, {
689
- key: "getIdFromContainer",
690
- value: function getIdFromContainer(glContainer) {
691
- var config = LayoutUtils.getComponentConfigFromContainer(glContainer);
703
+ return name;
704
+ }
705
+ /**
706
+ * Put focus on the first "input" element (input, button, select, textarea) within an element
707
+ * If element is null or input element not found, does nothing
708
+ * @param {DOMElement} element The element to put focus in.
709
+ * @param {String} selector The first element matching this selector will be focused.
710
+ * @returns {DOMElement} The element that was focused, null if not focused
711
+ */
712
+
692
713
 
693
- if (config) {
694
- return config.id;
695
- }
714
+ static focusElement(element) {
715
+ var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : LayoutUtils.DEFAULT_FOCUS_SELECTOR;
696
716
 
717
+ if (element == null) {
697
718
  return null;
698
719
  }
699
- /**
700
- * Retrieve the ID of the panel provided
701
- * @param {Component} panel The panel to get the ID for
702
- * @returns {string|null} Panel ID
703
- */
704
-
705
- }, {
706
- key: "getIdFromPanel",
707
- value: function getIdFromPanel(panel) {
708
- var glContainer = panel.props.glContainer;
709
- return LayoutUtils.getIdFromContainer(glContainer);
710
- }
711
- /**
712
- * Get component name from the panel instance
713
- * @param {Component} panel Panel to get component name for
714
- * @returns {string} Component name or null if unable to retrieve name
715
- */
716
-
717
- }, {
718
- key: "getComponentNameFromPanel",
719
- value: function getComponentNameFromPanel(panel) {
720
- var _config$component;
721
-
722
- var glContainer = panel.props.glContainer;
723
- var config = LayoutUtils.getComponentConfigFromContainer(glContainer);
724
- return (_config$component = config === null || config === void 0 ? void 0 : config.component) !== null && _config$component !== void 0 ? _config$component : null;
725
- }
726
- /**
727
- * Get component name for wrapped and un-wrapped components
728
- * @param {Component} component Component to get name for
729
- * @returns {string} Component name
730
- * @throws If displayName for the component is not defined
731
- */
732
-
733
- }, {
734
- key: "getComponentName",
735
- value: function getComponentName(component) {
736
- var _component$WrappedCom, _component$WrappedCom2;
737
-
738
- var name = (_component$WrappedCom = (_component$WrappedCom2 = component.WrappedComponent) === null || _component$WrappedCom2 === void 0 ? void 0 : _component$WrappedCom2.displayName) !== null && _component$WrappedCom !== void 0 ? _component$WrappedCom : component.displayName;
739
-
740
- if (name == null) {
741
- throw new Error('Component displayName not defined', component);
742
- }
743
720
 
744
- return name;
745
- }
746
- /**
747
- * Put focus on the first "input" element (input, button, select, textarea) within an element
748
- * If element is null or input element not found, does nothing
749
- * @param {DOMElement} element The element to put focus in.
750
- * @param {String} selector The first element matching this selector will be focused.
751
- * @returns {DOMElement} The element that was focused, null if not focused
752
- */
721
+ var focusElement = element.querySelector(selector);
753
722
 
754
- }, {
755
- key: "focusElement",
756
- value: function focusElement(element) {
757
- var selector = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : LayoutUtils.DEFAULT_FOCUS_SELECTOR;
723
+ if (focusElement == null) {
724
+ return null;
725
+ }
758
726
 
759
- if (element == null) {
760
- return null;
761
- }
727
+ focusElement.focus();
728
+ return focusElement;
729
+ }
730
+ /**
731
+ * Get a promise that initializes when layout is initialized
732
+ * @param {GoldenLayout} layout The layout to await initialization on
733
+ * @returns Promise that resolves when layout is initialized
734
+ */
762
735
 
763
- var focusElement = element.querySelector(selector);
764
736
 
765
- if (focusElement == null) {
766
- return null;
737
+ static onInitialized(layout) {
738
+ return new Promise(resolve => {
739
+ if (layout.isInitialised) {
740
+ resolve();
741
+ return;
767
742
  }
768
743
 
769
- focusElement.focus();
770
- return focusElement;
771
- }
772
- /**
773
- * Get a promise that initializes when layout is initialized
774
- * @param {GoldenLayout} layout The layout to await initialization on
775
- * @returns Promise that resolves when layout is initialized
776
- */
777
-
778
- }, {
779
- key: "onInitialized",
780
- value: function onInitialized(layout) {
781
- return new Promise(function (resolve) {
782
- if (layout.isInitialised) {
783
- resolve();
784
- return;
785
- }
786
-
787
- var onInit = function onInit() {
788
- layout.off('initialised', onInit);
789
- resolve();
790
- };
744
+ var onInit = () => {
745
+ layout.off('initialised', onInit);
746
+ resolve();
747
+ };
791
748
 
792
- layout.on('initialised', onInit);
793
- });
794
- }
795
- }]);
749
+ layout.on('initialised', onInit);
750
+ });
751
+ }
796
752
 
797
- return LayoutUtils;
798
- }();
753
+ }
799
754
 
800
755
  _defineProperty(LayoutUtils, "DEFAULT_FOCUS_SELECTOR", 'input, select, textarea, button');
801
756