@api-client/ui 0.0.9 → 0.0.11
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/.eslintrc +8 -1
- package/demo/index.html +3 -0
- package/demo/layout/index.html +91 -0
- package/demo/layout/index.ts +182 -0
- package/dist/elements/layout/SplitItem.d.ts +1 -9
- package/dist/elements/layout/SplitItem.d.ts.map +1 -1
- package/dist/elements/layout/SplitItem.js +27 -20
- package/dist/elements/layout/SplitItem.js.map +1 -1
- package/dist/elements/layout/SplitLayout.d.ts +16 -14
- package/dist/elements/layout/SplitLayout.d.ts.map +1 -1
- package/dist/elements/layout/SplitLayout.js +47 -42
- package/dist/elements/layout/SplitLayout.js.map +1 -1
- package/dist/elements/layout/SplitPanel.d.ts +7 -2
- package/dist/elements/layout/SplitPanel.d.ts.map +1 -1
- package/dist/elements/layout/SplitPanel.js +130 -52
- package/dist/elements/layout/SplitPanel.js.map +1 -1
- package/dist/elements/layout/SplitView.d.ts.map +1 -1
- package/dist/elements/layout/SplitView.js +18 -14
- package/dist/elements/layout/SplitView.js.map +1 -1
- package/dist/elements/layout/type.d.ts +3 -3
- package/dist/elements/layout/type.d.ts.map +1 -1
- package/dist/elements/layout/type.js.map +1 -1
- package/dist/elements/schema-design/DataModelVisualizationElement.d.ts.map +1 -1
- package/dist/elements/schema-design/DataModelVisualizationElement.js +18 -1
- package/dist/elements/schema-design/DataModelVisualizationElement.js.map +1 -1
- package/dist/pages/http-project/HttpClientCommands.d.ts.map +1 -1
- package/dist/pages/http-project/HttpClientCommands.js +28 -12
- package/dist/pages/http-project/HttpClientCommands.js.map +1 -1
- package/package.json +2 -1
- package/src/elements/layout/SplitItem.ts +29 -21
- package/src/elements/layout/SplitLayout.ts +53 -43
- package/src/elements/layout/SplitPanel.ts +140 -57
- package/src/elements/layout/SplitView.ts +18 -15
- package/src/elements/layout/type.ts +3 -4
- package/src/elements/schema-design/DataModelVisualizationElement.ts +18 -1
- package/src/pages/http-project/HttpClientCommands.ts +28 -12
- package/test/elements/layout/SplitItem.test.ts +76 -75
- package/test/elements/layout/SplitLayoutManager.test.ts +70 -69
- package/test/elements/layout/SplitPanel.test.ts +10 -7
- package/tsconfig.eslint.json +8 -0
- package/web-test-runner.config.mjs +4 -1
- package/dist/define/layout/layout-panel.d.ts +0 -7
- package/dist/define/layout/layout-panel.d.ts.map +0 -1
- package/dist/define/layout/layout-panel.js +0 -3
- package/dist/define/layout/layout-panel.js.map +0 -1
- package/dist/elements/layout/LayoutManager.d.ts +0 -327
- package/dist/elements/layout/LayoutManager.d.ts.map +0 -1
- package/dist/elements/layout/LayoutManager.js +0 -747
- package/dist/elements/layout/LayoutManager.js.map +0 -1
- package/dist/elements/layout/LayoutPanelElement.d.ts +0 -62
- package/dist/elements/layout/LayoutPanelElement.d.ts.map +0 -1
- package/dist/elements/layout/LayoutPanelElement.js +0 -628
- package/dist/elements/layout/LayoutPanelElement.js.map +0 -1
- package/src/define/layout/layout-panel.ts +0 -9
- package/src/elements/layout/LayoutManager.ts +0 -930
- package/src/elements/layout/LayoutPanelElement.ts +0 -651
|
@@ -1,747 +0,0 @@
|
|
|
1
|
-
/* eslint-disable prefer-destructuring */
|
|
2
|
-
/* eslint-disable max-classes-per-file */
|
|
3
|
-
import { html } from 'lit';
|
|
4
|
-
import { Events } from '../../events/Events.js';
|
|
5
|
-
import '../../define/layout/layout-panel.js';
|
|
6
|
-
var PanelState;
|
|
7
|
-
(function (PanelState) {
|
|
8
|
-
PanelState[PanelState["Idle"] = 0] = "Idle";
|
|
9
|
-
PanelState[PanelState["Busy"] = 1] = "Busy";
|
|
10
|
-
})(PanelState || (PanelState = {}));
|
|
11
|
-
let panelId = 0;
|
|
12
|
-
export class LayoutPanel {
|
|
13
|
-
get hasPanels() {
|
|
14
|
-
return this.panels.length > 0;
|
|
15
|
-
}
|
|
16
|
-
get hasItems() {
|
|
17
|
-
return this.items.length > 0;
|
|
18
|
-
}
|
|
19
|
-
static fromSchema(state, manager, parent) {
|
|
20
|
-
const panel = new LayoutPanel(manager, parent);
|
|
21
|
-
panel.id = state.id;
|
|
22
|
-
panel.selected = state.selected;
|
|
23
|
-
panel.layout = state.layout;
|
|
24
|
-
if (Array.isArray(state.items)) {
|
|
25
|
-
panel.items = state.items.map(i => ({ ...i }));
|
|
26
|
-
}
|
|
27
|
-
if (Array.isArray(state.panels)) {
|
|
28
|
-
panel.panels = state.panels.map(i => LayoutPanel.fromSchema(i, manager, panel));
|
|
29
|
-
}
|
|
30
|
-
return panel;
|
|
31
|
-
}
|
|
32
|
-
constructor(manager, parent) {
|
|
33
|
-
this.id = panelId++;
|
|
34
|
-
this.layout = 'horizontal';
|
|
35
|
-
this.panels = [];
|
|
36
|
-
this.items = [];
|
|
37
|
-
/**
|
|
38
|
-
* The current state of the panel.
|
|
39
|
-
*/
|
|
40
|
-
this.state = PanelState.Idle;
|
|
41
|
-
/**
|
|
42
|
-
* The computed size value for each item.
|
|
43
|
-
* The value of `undefined` means "auto".
|
|
44
|
-
*/
|
|
45
|
-
this.sizes = [];
|
|
46
|
-
this.manager = manager;
|
|
47
|
-
this.state = PanelState.Idle;
|
|
48
|
-
this.parent = parent;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* @returns Returns a **copy** of the items array sorted by index.
|
|
52
|
-
*/
|
|
53
|
-
sortedItems() {
|
|
54
|
-
const { items } = this;
|
|
55
|
-
return [...items].sort((a, b) => (a.index || 0) - (b.index || 0));
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* @returns True when the panel accepts drop events.
|
|
59
|
-
*/
|
|
60
|
-
canDrop() {
|
|
61
|
-
if (this.hasItems) {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
return !this.hasPanels;
|
|
65
|
-
}
|
|
66
|
-
nextIndex() {
|
|
67
|
-
let result = 0;
|
|
68
|
-
if (!this.items.length) {
|
|
69
|
-
return result;
|
|
70
|
-
}
|
|
71
|
-
this.items.forEach((item) => {
|
|
72
|
-
const { index = 0 } = item;
|
|
73
|
-
if (result < index) {
|
|
74
|
-
result = index;
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
return result + 1;
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Adds an item to the layout.
|
|
81
|
-
*
|
|
82
|
-
* @param item The item to add
|
|
83
|
-
* @param opts Layout adding item options
|
|
84
|
-
* @returns Whether a new item was added to the layout. false when the item is already in the layout panel.
|
|
85
|
-
*/
|
|
86
|
-
addItem(item, opts = {}) {
|
|
87
|
-
const { region = 'center' } = opts;
|
|
88
|
-
const hasItem = region === 'center' && this.items.some(i => i.key === item.key);
|
|
89
|
-
if (hasItem) {
|
|
90
|
-
this.selected = item.key;
|
|
91
|
-
this.manager.changed();
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
94
|
-
const hasIndex = typeof opts.index === 'number';
|
|
95
|
-
const index = !hasIndex ? this.nextIndex() : opts.index;
|
|
96
|
-
if (region === 'center' || (!this.hasItems && !this.hasPanels)) {
|
|
97
|
-
if (hasIndex) {
|
|
98
|
-
this.increaseIndex(index + 1);
|
|
99
|
-
}
|
|
100
|
-
this.manager.nameItem(item);
|
|
101
|
-
this.items.push({ ...item, index });
|
|
102
|
-
this.selected = item.key;
|
|
103
|
-
this.manager.changed();
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
let panel;
|
|
107
|
-
if (region === 'east') {
|
|
108
|
-
panel = this.split({
|
|
109
|
-
layout: 'horizontal',
|
|
110
|
-
itemsTarget: 0,
|
|
111
|
-
})[1];
|
|
112
|
-
}
|
|
113
|
-
else if (region === 'west') {
|
|
114
|
-
panel = this.split({
|
|
115
|
-
layout: 'horizontal',
|
|
116
|
-
itemsTarget: 1,
|
|
117
|
-
})[0];
|
|
118
|
-
}
|
|
119
|
-
else if (region === 'south') {
|
|
120
|
-
panel = this.split({
|
|
121
|
-
layout: 'vertical',
|
|
122
|
-
itemsTarget: 0,
|
|
123
|
-
})[1];
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
panel = this.split({
|
|
127
|
-
layout: 'horizontal',
|
|
128
|
-
itemsTarget: 1,
|
|
129
|
-
})[0];
|
|
130
|
-
}
|
|
131
|
-
panel.addItem(item, { index });
|
|
132
|
-
this.manager.changed();
|
|
133
|
-
return true;
|
|
134
|
-
}
|
|
135
|
-
/**
|
|
136
|
-
* Splits this panel into 2 panels.
|
|
137
|
-
* This to be used when the panel has no other panels. Only items are allowed.
|
|
138
|
-
* It produces 2 new panels and moves the items to the first one leaving the other one available.
|
|
139
|
-
*/
|
|
140
|
-
split(opts = {}) {
|
|
141
|
-
const { layout = 'horizontal', itemsTarget = 0 } = opts;
|
|
142
|
-
if (this.hasPanels) {
|
|
143
|
-
throw new Error(`Invalid state. Panels can be split only when containing items only.`);
|
|
144
|
-
}
|
|
145
|
-
this.layout = layout;
|
|
146
|
-
const { items, selected } = this;
|
|
147
|
-
this.items = [];
|
|
148
|
-
this.selected = undefined;
|
|
149
|
-
const p1 = new LayoutPanel(this.manager, this);
|
|
150
|
-
const p2 = new LayoutPanel(this.manager, this);
|
|
151
|
-
this.panels = [p1, p2];
|
|
152
|
-
this.panels[itemsTarget].items = items;
|
|
153
|
-
this.panels[itemsTarget].selected = selected;
|
|
154
|
-
this.manager.changed();
|
|
155
|
-
return this.panels;
|
|
156
|
-
}
|
|
157
|
-
unsplit() {
|
|
158
|
-
const { items, selected } = this.panels[0];
|
|
159
|
-
this.panels = [];
|
|
160
|
-
this.items = items;
|
|
161
|
-
this.selected = selected;
|
|
162
|
-
this.manager.changed();
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Decreases items index by 1 to all items with index at least equal to `fromIndex`.
|
|
166
|
-
* @param fromIndex The minimal index to affect.
|
|
167
|
-
*/
|
|
168
|
-
decreaseIndex(fromIndex) {
|
|
169
|
-
for (const item of this.items) {
|
|
170
|
-
const { index = 0 } = item;
|
|
171
|
-
if (index >= fromIndex && index > 0) {
|
|
172
|
-
item.index -= 1;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
/**
|
|
177
|
-
* Increases items index by 1 to all items with index at least equal to `fromIndex`.
|
|
178
|
-
* @param fromIndex The minimal index to affect.
|
|
179
|
-
*/
|
|
180
|
-
increaseIndex(fromIndex) {
|
|
181
|
-
for (const item of this.items) {
|
|
182
|
-
const { index = 0 } = item;
|
|
183
|
-
if (index >= fromIndex) {
|
|
184
|
-
item.index += 1;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
/**
|
|
189
|
-
* Removes an item from the layout
|
|
190
|
-
* @param key The key of the item.
|
|
191
|
-
* @returns The removed item, if any.
|
|
192
|
-
*/
|
|
193
|
-
removeItem(key) {
|
|
194
|
-
const index = this.items.findIndex(i => i.key === key);
|
|
195
|
-
if (index < 0) {
|
|
196
|
-
return undefined;
|
|
197
|
-
}
|
|
198
|
-
const removed = this.items[index];
|
|
199
|
-
this.items.splice(index, 1);
|
|
200
|
-
this.decreaseIndex(removed.index || 0);
|
|
201
|
-
if (this.items.length === 0) {
|
|
202
|
-
// remove panel
|
|
203
|
-
if (this.parent) {
|
|
204
|
-
this.parent.removePanel(this.id);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (this.selected === key) {
|
|
208
|
-
let nextKey;
|
|
209
|
-
if (this.items[index]) {
|
|
210
|
-
nextKey = this.items[index].key;
|
|
211
|
-
}
|
|
212
|
-
else if (this.items[index - 1]) {
|
|
213
|
-
nextKey = this.items[index - 1].key;
|
|
214
|
-
}
|
|
215
|
-
this.selected = nextKey;
|
|
216
|
-
}
|
|
217
|
-
this.manager.dispatchEvent(new CustomEvent('closetab', {
|
|
218
|
-
bubbles: true,
|
|
219
|
-
cancelable: true,
|
|
220
|
-
composed: true,
|
|
221
|
-
detail: key,
|
|
222
|
-
}));
|
|
223
|
-
this.manager.changed();
|
|
224
|
-
this.manager.forceUpdateLayout(this.id);
|
|
225
|
-
return removed;
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* @param key The key of the item to perform a relative operation from.
|
|
229
|
-
* @param dir The direction to which close other items. Default to both directions leaving only the `key` item
|
|
230
|
-
*/
|
|
231
|
-
relativeClose(key, dir = 'both') {
|
|
232
|
-
const index = this.items.findIndex(i => i.key === key);
|
|
233
|
-
if (index < 0) {
|
|
234
|
-
return;
|
|
235
|
-
}
|
|
236
|
-
const item = this.items[index];
|
|
237
|
-
if (dir === 'both') {
|
|
238
|
-
this.items = [item];
|
|
239
|
-
this.selected = item.key;
|
|
240
|
-
}
|
|
241
|
-
else if (dir === 'left') {
|
|
242
|
-
this.items = this.items.splice(index);
|
|
243
|
-
this.selected = item.key;
|
|
244
|
-
}
|
|
245
|
-
else {
|
|
246
|
-
this.items = this.items.splice(0, index + 1);
|
|
247
|
-
this.selected = item.key;
|
|
248
|
-
}
|
|
249
|
-
this.manager.changed();
|
|
250
|
-
this.manager.forceUpdateLayout(this.id);
|
|
251
|
-
}
|
|
252
|
-
removePanel(id) {
|
|
253
|
-
const index = this.panels.findIndex(p => p.id === id);
|
|
254
|
-
if (index < 0) {
|
|
255
|
-
return;
|
|
256
|
-
}
|
|
257
|
-
this.panels.splice(index, 1);
|
|
258
|
-
if (this.panels.length === 1) {
|
|
259
|
-
this.unsplit();
|
|
260
|
-
}
|
|
261
|
-
this.manager.changed();
|
|
262
|
-
this.manager.forceUpdateLayout(this.id);
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Moves an item to a new index.
|
|
266
|
-
*
|
|
267
|
-
* @param key The item key
|
|
268
|
-
* @param toIndex The new index. When not set it moves the item to the end.
|
|
269
|
-
*/
|
|
270
|
-
moveItem(key, toIndex) {
|
|
271
|
-
const item = this.items.find(i => i.key === key);
|
|
272
|
-
if (!item) {
|
|
273
|
-
return;
|
|
274
|
-
}
|
|
275
|
-
const hasIndex = typeof toIndex === 'number';
|
|
276
|
-
if (hasIndex && item.index === toIndex) {
|
|
277
|
-
return;
|
|
278
|
-
}
|
|
279
|
-
let hasTargetAtTarget = false;
|
|
280
|
-
if (hasIndex) {
|
|
281
|
-
hasTargetAtTarget = !!this.items[toIndex];
|
|
282
|
-
}
|
|
283
|
-
if (item.index !== undefined) {
|
|
284
|
-
this.decreaseIndex(item.index);
|
|
285
|
-
}
|
|
286
|
-
const finalIndex = hasIndex ? toIndex : this.nextIndex();
|
|
287
|
-
if (hasTargetAtTarget) {
|
|
288
|
-
this.increaseIndex(finalIndex);
|
|
289
|
-
}
|
|
290
|
-
item.index = finalIndex;
|
|
291
|
-
this.manager.changed();
|
|
292
|
-
this.manager.forceUpdateLayout(this.id);
|
|
293
|
-
}
|
|
294
|
-
rename(key, label) {
|
|
295
|
-
const item = this.items.find(i => i.key === key);
|
|
296
|
-
if (!item) {
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
item.label = label;
|
|
300
|
-
this.manager.changed();
|
|
301
|
-
this.manager.forceUpdateLayout(this.id);
|
|
302
|
-
}
|
|
303
|
-
toJSON() {
|
|
304
|
-
const result = {
|
|
305
|
-
id: this.id,
|
|
306
|
-
layout: this.layout,
|
|
307
|
-
};
|
|
308
|
-
if (this.items.length) {
|
|
309
|
-
result.items = this.items.map(i => ({ ...i }));
|
|
310
|
-
}
|
|
311
|
-
if (this.panels) {
|
|
312
|
-
result.panels = this.panels.map(i => i.toJSON());
|
|
313
|
-
}
|
|
314
|
-
if (this.selected) {
|
|
315
|
-
result.selected = this.selected;
|
|
316
|
-
}
|
|
317
|
-
return result;
|
|
318
|
-
}
|
|
319
|
-
panelTemplate(panel, itemCallback) {
|
|
320
|
-
const { layout, panels, items, selected } = panel;
|
|
321
|
-
const { manager } = this;
|
|
322
|
-
const { dragTypes, constrain } = manager.opts;
|
|
323
|
-
let content;
|
|
324
|
-
if (panels.length) {
|
|
325
|
-
content = panels.map(p => this.panelTemplate(p, itemCallback));
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
content = items.map(p => this.itemTemplate(p, p.key === selected, itemCallback));
|
|
329
|
-
}
|
|
330
|
-
const valid = content.filter(i => !!i);
|
|
331
|
-
if (!valid.length) {
|
|
332
|
-
return undefined;
|
|
333
|
-
}
|
|
334
|
-
return html `
|
|
335
|
-
<layout-panel
|
|
336
|
-
layout="${layout}"
|
|
337
|
-
.dragTypes="${dragTypes}"
|
|
338
|
-
.panel="${panel}"
|
|
339
|
-
.layoutId="${panel.id}"
|
|
340
|
-
?constrain="${constrain}"
|
|
341
|
-
>
|
|
342
|
-
${content}
|
|
343
|
-
</layout-panel>
|
|
344
|
-
`;
|
|
345
|
-
}
|
|
346
|
-
itemTemplate(item, visible, itemCallback) {
|
|
347
|
-
return itemCallback(item, visible);
|
|
348
|
-
}
|
|
349
|
-
render(itemCallback) {
|
|
350
|
-
return this.panelTemplate(this, itemCallback);
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
/**
|
|
354
|
-
* Layout manager for API Client apps.
|
|
355
|
-
*
|
|
356
|
-
* Supports:
|
|
357
|
-
* - layout splitting depending on the selected region (east, west, north, south)
|
|
358
|
-
* - drag and drop of items into the layout
|
|
359
|
-
* - auto storing and restoring layout state from the application local storage.
|
|
360
|
-
* - adding items to the last focused panel
|
|
361
|
-
*
|
|
362
|
-
* Limitations
|
|
363
|
-
* - the rendered content has to be focusable (tabindex must be set) in order to detect active panel
|
|
364
|
-
*/
|
|
365
|
-
export class LayoutManager extends EventTarget {
|
|
366
|
-
/**
|
|
367
|
-
* An active panel
|
|
368
|
-
*/
|
|
369
|
-
get activePanel() {
|
|
370
|
-
if (!this._activePanel) {
|
|
371
|
-
this._activePanel = this.findFirstItemsPanel();
|
|
372
|
-
}
|
|
373
|
-
return this._activePanel;
|
|
374
|
-
}
|
|
375
|
-
constructor(opts = {}) {
|
|
376
|
-
super();
|
|
377
|
-
this.panels = [];
|
|
378
|
-
this.isDirty = false;
|
|
379
|
-
this.storing = false;
|
|
380
|
-
this.opts = opts;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* @param itemCallback The callback called when rendering an item in layout view.
|
|
384
|
-
* @returns The template for the page layout.
|
|
385
|
-
*/
|
|
386
|
-
render(itemCallback) {
|
|
387
|
-
const result = [];
|
|
388
|
-
this.panels.forEach(p => {
|
|
389
|
-
const content = p.render(itemCallback);
|
|
390
|
-
if (content) {
|
|
391
|
-
result.push(content);
|
|
392
|
-
}
|
|
393
|
-
});
|
|
394
|
-
return result;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Initializes the manager.
|
|
398
|
-
*
|
|
399
|
-
* @param restore Previously stored layout state, if any.
|
|
400
|
-
*/
|
|
401
|
-
async initialize(restore) {
|
|
402
|
-
if (restore) {
|
|
403
|
-
this.restore(restore);
|
|
404
|
-
}
|
|
405
|
-
else if (this.opts.storeKey && this.opts.autoStore) {
|
|
406
|
-
await this.restoreLayout(this.opts.storeKey);
|
|
407
|
-
}
|
|
408
|
-
if (!this.panels.length) {
|
|
409
|
-
this.panels.push(new LayoutPanel(this));
|
|
410
|
-
}
|
|
411
|
-
document.body.addEventListener('focusin', this._focusInHandler.bind(this));
|
|
412
|
-
}
|
|
413
|
-
restore(restore) {
|
|
414
|
-
if (Array.isArray(restore.panels)) {
|
|
415
|
-
this.panels = restore.panels.map(i => LayoutPanel.fromSchema(i, this));
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
/**
|
|
419
|
-
* Informs the screen that something has changed
|
|
420
|
-
*/
|
|
421
|
-
changed() {
|
|
422
|
-
this.dispatchEvent(new Event('change'));
|
|
423
|
-
this.autoStore();
|
|
424
|
-
}
|
|
425
|
-
/**
|
|
426
|
-
* Dispatches the `nameitem` event.
|
|
427
|
-
* The detail object has the item to be added to the items.
|
|
428
|
-
* The event handler can manipulate properties of the item, except for the index which will be set by the manager.
|
|
429
|
-
*
|
|
430
|
-
* @param item The item to notify.
|
|
431
|
-
*/
|
|
432
|
-
nameItem(item) {
|
|
433
|
-
this.dispatchEvent(new CustomEvent('nameitem', {
|
|
434
|
-
detail: item,
|
|
435
|
-
}));
|
|
436
|
-
}
|
|
437
|
-
/**
|
|
438
|
-
* Serializes the layout state to a JSON safe object.
|
|
439
|
-
* This is automatically called when passing this object to `JSON.stringify()`.
|
|
440
|
-
*/
|
|
441
|
-
toJSON() {
|
|
442
|
-
const result = {
|
|
443
|
-
panels: this.panels.map(i => i.toJSON()),
|
|
444
|
-
};
|
|
445
|
-
return result;
|
|
446
|
-
}
|
|
447
|
-
autoStore() {
|
|
448
|
-
const { autoStore, storeKey } = this.opts;
|
|
449
|
-
if (!autoStore || !storeKey) {
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
this.storeLayout(storeKey);
|
|
453
|
-
}
|
|
454
|
-
async storeLayout(key) {
|
|
455
|
-
if (this.storing) {
|
|
456
|
-
this.isDirty = true;
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
this.storing = true;
|
|
460
|
-
try {
|
|
461
|
-
await Events.Config.Local.set(key, this.toJSON());
|
|
462
|
-
}
|
|
463
|
-
finally {
|
|
464
|
-
this.storing = false;
|
|
465
|
-
}
|
|
466
|
-
if (this.isDirty) {
|
|
467
|
-
this.isDirty = false;
|
|
468
|
-
await this.storeLayout(key);
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
async restoreLayout(key) {
|
|
472
|
-
try {
|
|
473
|
-
const data = await Events.Config.Local.get(key);
|
|
474
|
-
if (data) {
|
|
475
|
-
this.restore(data);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
catch (e) {
|
|
479
|
-
//
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
_focusInHandler(e) {
|
|
483
|
-
const layout = this.findLayout(e);
|
|
484
|
-
if (layout) {
|
|
485
|
-
const id = Number(layout.dataset.panel);
|
|
486
|
-
const { activePanel } = this;
|
|
487
|
-
if (activePanel && activePanel.id === id) {
|
|
488
|
-
return;
|
|
489
|
-
}
|
|
490
|
-
this._activePanel = this.findPanel(id);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
findLayout(e, last = true) {
|
|
494
|
-
const path = e.composedPath();
|
|
495
|
-
if (!last) {
|
|
496
|
-
path.reverse();
|
|
497
|
-
}
|
|
498
|
-
while (path.length) {
|
|
499
|
-
const node = path.shift();
|
|
500
|
-
if (node.nodeType !== Node.ELEMENT_NODE) {
|
|
501
|
-
continue;
|
|
502
|
-
}
|
|
503
|
-
if (node.localName === 'layout-panel') {
|
|
504
|
-
return node;
|
|
505
|
-
}
|
|
506
|
-
}
|
|
507
|
-
return undefined;
|
|
508
|
-
}
|
|
509
|
-
/**
|
|
510
|
-
* Finds a panel by id.
|
|
511
|
-
*
|
|
512
|
-
* @param id The id of the panel.
|
|
513
|
-
* @param parent THe parent panel to start searching from
|
|
514
|
-
* @returns The panel if found
|
|
515
|
-
*/
|
|
516
|
-
findPanel(id, parent) {
|
|
517
|
-
const panels = parent && parent.panels || this.panels;
|
|
518
|
-
for (const p of panels) {
|
|
519
|
-
if (p.id === id) {
|
|
520
|
-
return p;
|
|
521
|
-
}
|
|
522
|
-
const child = this.findPanel(id, p);
|
|
523
|
-
if (child) {
|
|
524
|
-
return child;
|
|
525
|
-
}
|
|
526
|
-
}
|
|
527
|
-
return undefined;
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Finds a first panel that can accept items.
|
|
531
|
-
* This will be a panel that has no other panels.
|
|
532
|
-
*/
|
|
533
|
-
findFirstItemsPanel(parent) {
|
|
534
|
-
const panels = parent && parent.panels || this.panels;
|
|
535
|
-
for (const p of panels) {
|
|
536
|
-
if (!p.hasPanels) {
|
|
537
|
-
return p;
|
|
538
|
-
}
|
|
539
|
-
const child = this.findFirstItemsPanel(p);
|
|
540
|
-
if (child) {
|
|
541
|
-
return child;
|
|
542
|
-
}
|
|
543
|
-
}
|
|
544
|
-
return undefined;
|
|
545
|
-
}
|
|
546
|
-
/**
|
|
547
|
-
* Finds a panel for the item.
|
|
548
|
-
* @param key the key of the item to find.
|
|
549
|
-
*/
|
|
550
|
-
findItemPanel(key, parent) {
|
|
551
|
-
const panels = parent && parent.panels || this.panels;
|
|
552
|
-
for (const p of panels) {
|
|
553
|
-
const { items } = p;
|
|
554
|
-
for (const i of items) {
|
|
555
|
-
if (i.key === key) {
|
|
556
|
-
return p;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
const deep = this.findItemPanel(key, p);
|
|
560
|
-
if (deep) {
|
|
561
|
-
return deep;
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
return undefined;
|
|
565
|
-
}
|
|
566
|
-
/**
|
|
567
|
-
* Finds a layout item.
|
|
568
|
-
* @param key the key of the item to find.
|
|
569
|
-
*/
|
|
570
|
-
findItem(key, parent) {
|
|
571
|
-
const panels = parent && parent.panels || this.panels;
|
|
572
|
-
for (const p of panels) {
|
|
573
|
-
const { items } = p;
|
|
574
|
-
for (const i of items) {
|
|
575
|
-
if (i.key === key) {
|
|
576
|
-
return i;
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
const deep = this.findItem(key, p);
|
|
580
|
-
if (deep) {
|
|
581
|
-
return deep;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
return undefined;
|
|
585
|
-
}
|
|
586
|
-
*parentItemIterator(key, parent) {
|
|
587
|
-
const panels = parent ? parent.panels : this.panels;
|
|
588
|
-
for (const p of panels) {
|
|
589
|
-
const { items } = p;
|
|
590
|
-
for (const i of items) {
|
|
591
|
-
if (i.parent === key) {
|
|
592
|
-
yield i;
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
for (const result of this.parentItemIterator(key, p)) {
|
|
596
|
-
yield result;
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
/**
|
|
601
|
-
* Adds an item to the active panel.
|
|
602
|
-
*
|
|
603
|
-
* @param item The item to add.
|
|
604
|
-
*/
|
|
605
|
-
addItem(item) {
|
|
606
|
-
const { activePanel } = this;
|
|
607
|
-
if (!activePanel) {
|
|
608
|
-
throw new Error(`Unable to determine an active panel.`);
|
|
609
|
-
}
|
|
610
|
-
activePanel.addItem(item);
|
|
611
|
-
this.forceUpdateLayout();
|
|
612
|
-
}
|
|
613
|
-
/**
|
|
614
|
-
* Removes an item from layout.
|
|
615
|
-
* @param key The key of the item to remove.
|
|
616
|
-
*/
|
|
617
|
-
removeItem(key) {
|
|
618
|
-
const panel = this.findItemPanel(key);
|
|
619
|
-
if (panel) {
|
|
620
|
-
panel.removeItem(key);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
/**
|
|
624
|
-
* @param key The key of the item to perform a relative operation from.
|
|
625
|
-
* @param dir The direction to which close other items. Default to both directions leaving only the `key` item
|
|
626
|
-
*/
|
|
627
|
-
relativeClose(key, dir = 'both') {
|
|
628
|
-
const panel = this.findItemPanel(key);
|
|
629
|
-
if (panel) {
|
|
630
|
-
panel.relativeClose(key, dir);
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
/**
|
|
634
|
-
* Requests an update on a layout.
|
|
635
|
-
*
|
|
636
|
-
* @param id The id of the panel. When not set it uses the active panel
|
|
637
|
-
*/
|
|
638
|
-
forceUpdateLayout(id) {
|
|
639
|
-
let key;
|
|
640
|
-
if (id === undefined) {
|
|
641
|
-
const panel = this.activePanel;
|
|
642
|
-
if (!panel) {
|
|
643
|
-
return;
|
|
644
|
-
}
|
|
645
|
-
key = panel.id;
|
|
646
|
-
}
|
|
647
|
-
else {
|
|
648
|
-
key = id;
|
|
649
|
-
}
|
|
650
|
-
const layout = document.querySelector(`layout-panel[layoutId="${key}"]`);
|
|
651
|
-
if (!layout) {
|
|
652
|
-
return;
|
|
653
|
-
}
|
|
654
|
-
layout.requestUpdate();
|
|
655
|
-
}
|
|
656
|
-
/**
|
|
657
|
-
* Moves a tab between panels or inside a panel
|
|
658
|
-
*
|
|
659
|
-
* @param fromPanel The id of the source panel of the item
|
|
660
|
-
* @param toPanel The id of the target panel of the item
|
|
661
|
-
* @param key The key of the item
|
|
662
|
-
* @param toIndex The index to which add the item. Default as the last.
|
|
663
|
-
*/
|
|
664
|
-
moveTab(fromPanel, toPanel, key, toIndex) {
|
|
665
|
-
const singlePanel = fromPanel === toPanel;
|
|
666
|
-
const from = this.findPanel(fromPanel);
|
|
667
|
-
if (!from) {
|
|
668
|
-
throw new Error(`The source layout panel not found.`);
|
|
669
|
-
}
|
|
670
|
-
if (singlePanel) {
|
|
671
|
-
from.moveItem(key, toIndex);
|
|
672
|
-
}
|
|
673
|
-
else {
|
|
674
|
-
const to = this.findPanel(toPanel);
|
|
675
|
-
if (!to) {
|
|
676
|
-
throw new Error(`The target layout panel not found.`);
|
|
677
|
-
}
|
|
678
|
-
const removed = from.removeItem(key);
|
|
679
|
-
if (!removed) {
|
|
680
|
-
return;
|
|
681
|
-
}
|
|
682
|
-
to.addItem(removed, { index: toIndex });
|
|
683
|
-
}
|
|
684
|
-
this.changed();
|
|
685
|
-
}
|
|
686
|
-
/**
|
|
687
|
-
* Finds the item's panel and renames the item.
|
|
688
|
-
*
|
|
689
|
-
* @param key The item's key
|
|
690
|
-
* @param label The new label
|
|
691
|
-
*/
|
|
692
|
-
rename(key, label) {
|
|
693
|
-
const panel = this.findItemPanel(key);
|
|
694
|
-
if (panel) {
|
|
695
|
-
panel.rename(key, label);
|
|
696
|
-
this.changed();
|
|
697
|
-
this.forceUpdateLayout(panel.id);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Requests to dispatch the `nameitem` event so the application can update the name of the tab.
|
|
702
|
-
*
|
|
703
|
-
* @param key The key of the item.
|
|
704
|
-
*/
|
|
705
|
-
requestNameUpdate(key) {
|
|
706
|
-
const item = this.findItem(key);
|
|
707
|
-
if (!item) {
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
|
-
const before = item.label;
|
|
711
|
-
this.nameItem(item);
|
|
712
|
-
if (before !== item.label) {
|
|
713
|
-
const panel = this.findItemPanel(key);
|
|
714
|
-
if (panel) {
|
|
715
|
-
this.forceUpdateLayout(panel.id);
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
/**
|
|
720
|
-
* Requests to dispatch the `nameitem` event so the application can update the name of a tab
|
|
721
|
-
* that has a parent.
|
|
722
|
-
*
|
|
723
|
-
* @param parent The key of the parent.
|
|
724
|
-
*/
|
|
725
|
-
parentNameUpdate(parent) {
|
|
726
|
-
for (const item of this.parentItemIterator(parent)) {
|
|
727
|
-
const before = item.label;
|
|
728
|
-
this.nameItem(item);
|
|
729
|
-
if (before !== item.label) {
|
|
730
|
-
const panel = this.findItemPanel(item.key);
|
|
731
|
-
if (panel) {
|
|
732
|
-
this.forceUpdateLayout(panel.id);
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
}
|
|
736
|
-
}
|
|
737
|
-
/**
|
|
738
|
-
* Finds all items in all panels that have specified parent.
|
|
739
|
-
* @param key The key of the parent to search for.
|
|
740
|
-
*/
|
|
741
|
-
removeByParent(key) {
|
|
742
|
-
for (const item of this.parentItemIterator(key)) {
|
|
743
|
-
this.removeItem(item.key);
|
|
744
|
-
}
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
//# sourceMappingURL=LayoutManager.js.map
|