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