@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
|
@@ -179,30 +179,38 @@ export class SplitItem implements ISplitItem {
|
|
|
179
179
|
return result;
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
/**
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
182
|
+
// /**
|
|
183
|
+
// * @returns The parent of the item. Returns undefined when the item was removed from layout.
|
|
184
|
+
// * @deprecated Use `getParents()` instead.
|
|
185
|
+
// */
|
|
186
|
+
// getParent(): SplitPanel | undefined {
|
|
187
|
+
// return this.manager.getParent(this.key);
|
|
188
|
+
// }
|
|
188
189
|
|
|
189
190
|
/**
|
|
190
|
-
*
|
|
191
|
+
* @returns The parent of the item. Returns undefined when the item was removed from layout.
|
|
191
192
|
*/
|
|
192
|
-
|
|
193
|
-
this.manager.
|
|
193
|
+
getParents(): SplitPanel[] {
|
|
194
|
+
return this.manager.getParents(this.key);
|
|
194
195
|
}
|
|
195
196
|
|
|
196
|
-
/**
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
197
|
+
// /**
|
|
198
|
+
// * Removes self from the layout. This removes the item from all panels.
|
|
199
|
+
// */
|
|
200
|
+
// remove(): void {
|
|
201
|
+
// this.manager.removeItem(this.key);
|
|
202
|
+
// }
|
|
203
|
+
|
|
204
|
+
// /**
|
|
205
|
+
// * Sets the item active in the parent layout.
|
|
206
|
+
// */
|
|
207
|
+
// setSelected(): void {
|
|
208
|
+
// const parent = this.getParent();
|
|
209
|
+
// if (parent) {
|
|
210
|
+
// parent.selected = this.key;
|
|
211
|
+
// this.notifyChange();
|
|
212
|
+
// }
|
|
213
|
+
// }
|
|
206
214
|
|
|
207
215
|
/**
|
|
208
216
|
* Updates the label and triggers side effects like layout and view update.
|
|
@@ -222,8 +230,8 @@ export class SplitItem implements ISplitItem {
|
|
|
222
230
|
}
|
|
223
231
|
|
|
224
232
|
updateView(): void {
|
|
225
|
-
const
|
|
226
|
-
panel
|
|
233
|
+
const panels = this.getParents();
|
|
234
|
+
panels.forEach(panel => panel.updateView());
|
|
227
235
|
}
|
|
228
236
|
|
|
229
237
|
notifyChange(): void {
|
|
@@ -3,7 +3,7 @@ import { TemplateResult } from "lit";
|
|
|
3
3
|
import { ISplitItem, SplitItem } from "./SplitItem.js";
|
|
4
4
|
import { ISplitPanel, SplitPanel } from "./SplitPanel.js";
|
|
5
5
|
import SplitView from "./SplitView.js";
|
|
6
|
-
import { IPanelObject, LayoutType,
|
|
6
|
+
import { IPanelObject, LayoutType, SplitDirection, SplitItemRenderCallback, SplitLayoutAddOptions, SplitLayoutInit, SplitPanelAddOptions } from "./type.js";
|
|
7
7
|
|
|
8
8
|
interface LayoutObject {
|
|
9
9
|
type: LayoutType;
|
|
@@ -33,6 +33,11 @@ export interface ISplitLayout {
|
|
|
33
33
|
active?: string;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
export interface ITabCloseDetail {
|
|
37
|
+
tab: string;
|
|
38
|
+
panel: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
36
41
|
/**
|
|
37
42
|
* Split layout manager creates a view where the application can put "items" into
|
|
38
43
|
* and render them inside "panels". The application can create as many panels as needed.
|
|
@@ -109,7 +114,7 @@ export class SplitLayout extends EventTarget {
|
|
|
109
114
|
return value as SplitPanel;
|
|
110
115
|
}
|
|
111
116
|
const item = value as SplitItem;
|
|
112
|
-
return this.
|
|
117
|
+
return this.getParents(item.key)[0];
|
|
113
118
|
}
|
|
114
119
|
|
|
115
120
|
/**
|
|
@@ -316,22 +321,25 @@ export class SplitLayout extends EventTarget {
|
|
|
316
321
|
}
|
|
317
322
|
|
|
318
323
|
/**
|
|
319
|
-
* Finds
|
|
320
|
-
*
|
|
321
|
-
*
|
|
324
|
+
* Finds parents an item or another panel is anchored to.
|
|
325
|
+
* An item can have multiple parents. A panel can only have a single parent.
|
|
326
|
+
*
|
|
327
|
+
* @param itemOrPanelKey The key of the panel or an item.
|
|
328
|
+
* @returns THe list of panels the item is added. It can only return up to 1 result when looking for a panel's parent.
|
|
322
329
|
*/
|
|
323
|
-
|
|
330
|
+
getParents(itemOrPanelKey: string): SplitPanel[] {
|
|
331
|
+
const result: SplitPanel[] = [];
|
|
324
332
|
for (const { type, value } of this.definitions.values()) {
|
|
325
333
|
if (type !== LayoutType.panel) {
|
|
326
334
|
continue;
|
|
327
335
|
}
|
|
328
336
|
const panel = value as SplitPanel;
|
|
329
|
-
const
|
|
330
|
-
if (
|
|
331
|
-
|
|
337
|
+
const has = panel.items.some(i => i.key === itemOrPanelKey);
|
|
338
|
+
if (has) {
|
|
339
|
+
result.push(panel);
|
|
332
340
|
}
|
|
333
341
|
}
|
|
334
|
-
return
|
|
342
|
+
return result;
|
|
335
343
|
}
|
|
336
344
|
|
|
337
345
|
/**
|
|
@@ -396,12 +404,15 @@ export class SplitLayout extends EventTarget {
|
|
|
396
404
|
* Do not call this method from the outside of the layout manager logic.
|
|
397
405
|
* It is a way to communicate a tab was closed.
|
|
398
406
|
*/
|
|
399
|
-
notifyTabClose(itemKey: string): void {
|
|
400
|
-
this.dispatchEvent(new CustomEvent('closetab', {
|
|
407
|
+
notifyTabClose(itemKey: string, panel: string): void {
|
|
408
|
+
this.dispatchEvent(new CustomEvent<ITabCloseDetail>('closetab', {
|
|
401
409
|
bubbles: true,
|
|
402
410
|
cancelable: true,
|
|
403
411
|
composed: true,
|
|
404
|
-
detail:
|
|
412
|
+
detail: {
|
|
413
|
+
tab: itemKey,
|
|
414
|
+
panel,
|
|
415
|
+
},
|
|
405
416
|
}));
|
|
406
417
|
}
|
|
407
418
|
|
|
@@ -431,10 +442,8 @@ export class SplitLayout extends EventTarget {
|
|
|
431
442
|
const before = item.label;
|
|
432
443
|
this.dispatchNameItem(item);
|
|
433
444
|
if (before !== item.label) {
|
|
434
|
-
const
|
|
435
|
-
|
|
436
|
-
this.updateView(panel.key);
|
|
437
|
-
}
|
|
445
|
+
const panels = this.getParents(item.key);
|
|
446
|
+
panels.forEach(panel => this.updateView(panel.key));
|
|
438
447
|
}
|
|
439
448
|
}
|
|
440
449
|
|
|
@@ -450,8 +459,8 @@ export class SplitLayout extends EventTarget {
|
|
|
450
459
|
const before = item.label;
|
|
451
460
|
this.dispatchNameItem(item);
|
|
452
461
|
if (before !== item.label) {
|
|
453
|
-
const
|
|
454
|
-
updatePanels.add(panel);
|
|
462
|
+
const panels = this.getParents(item.key);
|
|
463
|
+
panels.forEach(panel => updatePanels.add(panel));
|
|
455
464
|
}
|
|
456
465
|
}
|
|
457
466
|
|
|
@@ -532,7 +541,9 @@ export class SplitLayout extends EventTarget {
|
|
|
532
541
|
}
|
|
533
542
|
|
|
534
543
|
/**
|
|
535
|
-
* Removes an item from layout.
|
|
544
|
+
* Removes an item from the layout. This means removing an item from all panels.
|
|
545
|
+
* If you want to remove an item from a specific panel then find the panel first and then call `removeItem()`.
|
|
546
|
+
*
|
|
536
547
|
* @param key The key of the item to remove.
|
|
537
548
|
*/
|
|
538
549
|
removeItem(key: string): void {
|
|
@@ -540,27 +551,26 @@ export class SplitLayout extends EventTarget {
|
|
|
540
551
|
if (!item) {
|
|
541
552
|
return;
|
|
542
553
|
}
|
|
543
|
-
const
|
|
544
|
-
|
|
545
|
-
panel.removeItem(key);
|
|
546
|
-
}
|
|
554
|
+
const parents = this.getParents(key);
|
|
555
|
+
parents.forEach(parent => parent.removeChildItem(item));
|
|
547
556
|
}
|
|
548
557
|
|
|
549
|
-
/**
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
}
|
|
558
|
+
// /**
|
|
559
|
+
// * Removes other items relative to the `key` item.
|
|
560
|
+
// * @param key The key of the item to perform a relative operation from.
|
|
561
|
+
// * @param dir The direction to which close other items. Default to both directions leaving only the `key` item
|
|
562
|
+
// * @deprecated this function does not work as intended. Find the parent panel first and then call the `removeRelative()`.
|
|
563
|
+
// */
|
|
564
|
+
// removeRelative(key: string, dir?: SplitCloseDirection): void {
|
|
565
|
+
// const item = this.findItem(key);
|
|
566
|
+
// if (!item) {
|
|
567
|
+
// return;
|
|
568
|
+
// }
|
|
569
|
+
// const panel = item.getParent();
|
|
570
|
+
// if (panel) {
|
|
571
|
+
// panel.removeRelative(key, dir);
|
|
572
|
+
// }
|
|
573
|
+
// }
|
|
564
574
|
|
|
565
575
|
/**
|
|
566
576
|
* Moves a tab between panels or inside a panel
|
|
@@ -570,14 +580,14 @@ export class SplitLayout extends EventTarget {
|
|
|
570
580
|
* @param itemKey The key of the item
|
|
571
581
|
* @param toIndex The index to which add the item. Default as the last.
|
|
572
582
|
*/
|
|
573
|
-
moveItem(fromPanelKey: string, toPanelKey: string, itemKey: string,
|
|
583
|
+
moveItem(fromPanelKey: string, toPanelKey: string, itemKey: string, opts?: SplitLayoutAddOptions): void {
|
|
574
584
|
const singlePanel = fromPanelKey === toPanelKey;
|
|
575
585
|
const from = this.findPanel(fromPanelKey);
|
|
576
586
|
if (!from) {
|
|
577
587
|
throw new Error(`Source layout panel not found.`);
|
|
578
588
|
}
|
|
579
589
|
if (singlePanel) {
|
|
580
|
-
from.moveItem(itemKey,
|
|
590
|
+
from.moveItem(itemKey, opts);
|
|
581
591
|
} else {
|
|
582
592
|
const to = this.findPanel(toPanelKey);
|
|
583
593
|
if (!to) {
|
|
@@ -587,7 +597,7 @@ export class SplitLayout extends EventTarget {
|
|
|
587
597
|
if (!removed) {
|
|
588
598
|
throw new Error(`Item not found.`);
|
|
589
599
|
}
|
|
590
|
-
to.addItem(removed,
|
|
600
|
+
to.addItem(removed, opts);
|
|
591
601
|
}
|
|
592
602
|
this.notifyChange();
|
|
593
603
|
}
|
|
@@ -686,7 +696,7 @@ export class SplitLayout extends EventTarget {
|
|
|
686
696
|
panel = activePanel;
|
|
687
697
|
} else {
|
|
688
698
|
// any panel that has the item
|
|
689
|
-
panel = this.
|
|
699
|
+
[panel] = this.getParents(itemKey);
|
|
690
700
|
}
|
|
691
701
|
if (!panel) {
|
|
692
702
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
1
2
|
/* eslint-disable import/no-cycle */
|
|
2
3
|
import { html, TemplateResult } from "lit";
|
|
3
4
|
import { uuidV4 } from "@api-client/core/build/browser.js";
|
|
@@ -108,7 +109,7 @@ export class SplitPanel {
|
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
getParent(): SplitPanel | undefined {
|
|
111
|
-
return this.manager.
|
|
112
|
+
return this.manager.getParents(this.key)[0];
|
|
112
113
|
}
|
|
113
114
|
|
|
114
115
|
/**
|
|
@@ -226,6 +227,14 @@ export class SplitPanel {
|
|
|
226
227
|
return instance;
|
|
227
228
|
}
|
|
228
229
|
|
|
230
|
+
const panel = this.splitByRegion(region);
|
|
231
|
+
// we don't call request update here because
|
|
232
|
+
// the app has to redo the view rendering first as
|
|
233
|
+
// the panel purpose has changed.
|
|
234
|
+
return panel.addItem(item, { index });
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
protected splitByRegion(region: SplitRegion): SplitPanel {
|
|
229
238
|
let panel: SplitPanel;
|
|
230
239
|
if (region === 'east') {
|
|
231
240
|
[, panel] = this.split({
|
|
@@ -252,10 +261,7 @@ export class SplitPanel {
|
|
|
252
261
|
noSideEffects: true,
|
|
253
262
|
});
|
|
254
263
|
}
|
|
255
|
-
|
|
256
|
-
// the app has to redo the view rendering first as
|
|
257
|
-
// the panel purpose has changed.
|
|
258
|
-
return panel.addItem(item, { index });
|
|
264
|
+
return panel;
|
|
259
265
|
}
|
|
260
266
|
|
|
261
267
|
/**
|
|
@@ -273,11 +279,8 @@ export class SplitPanel {
|
|
|
273
279
|
this.items = [];
|
|
274
280
|
this.selected = undefined;
|
|
275
281
|
|
|
276
|
-
const p1 = this.addPanel()
|
|
277
|
-
const p2 = this.addPanel()
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
282
|
+
const p1 = this.addPanel();
|
|
283
|
+
const p2 = this.addPanel();
|
|
281
284
|
|
|
282
285
|
// const p1 = new SplitPanel(this.manager);
|
|
283
286
|
// const p2 = new SplitPanel(this.manager);
|
|
@@ -368,24 +371,19 @@ export class SplitPanel {
|
|
|
368
371
|
}
|
|
369
372
|
}
|
|
370
373
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
* @param key The `key` of the item.
|
|
374
|
-
* @returns The removed item, if any.
|
|
375
|
-
*/
|
|
376
|
-
removeItem(key: string, opts: SplitPanelRemoveItemOptions = {}): SplitItem | undefined {
|
|
377
|
-
const removed = this.manager.findItem(key);
|
|
378
|
-
if (!removed) {
|
|
379
|
-
return undefined;
|
|
380
|
-
}
|
|
381
|
-
const index = this.items.findIndex(i => i.key === key);
|
|
374
|
+
removeChildItem(item: SplitItem, opts: SplitPanelRemoveItemOptions = {}): SplitItem | undefined {
|
|
375
|
+
const index = this.items.findIndex(i => i.key === item.key);
|
|
382
376
|
if (index < 0) {
|
|
383
377
|
return undefined;
|
|
384
378
|
}
|
|
385
379
|
const itemInfo = this.items[index];
|
|
386
380
|
this.items.splice(index, 1);
|
|
387
|
-
this.
|
|
388
|
-
this.
|
|
381
|
+
this.decreaseIndex(item.index || 0);
|
|
382
|
+
const parents = this.manager.getParents(item.key);
|
|
383
|
+
if (!parents.length) {
|
|
384
|
+
// remove the definition since no other panel have this item.
|
|
385
|
+
this.manager.definitions.delete(itemInfo.key);
|
|
386
|
+
}
|
|
389
387
|
|
|
390
388
|
if (this.items.length === 0) {
|
|
391
389
|
// remove panel (self)
|
|
@@ -393,29 +391,82 @@ export class SplitPanel {
|
|
|
393
391
|
if (parent) {
|
|
394
392
|
parent.removePanel(this.key);
|
|
395
393
|
// Note, ignore `opts.noSideEffects` for tab close. It won't get dispatched elsewhere.
|
|
396
|
-
this.manager.notifyTabClose(key);
|
|
394
|
+
this.manager.notifyTabClose(item.key, this.key);
|
|
397
395
|
// no point doing the stuff below as the whole panel is removed.
|
|
398
|
-
return
|
|
396
|
+
return item;
|
|
399
397
|
}
|
|
400
398
|
}
|
|
401
|
-
|
|
399
|
+
|
|
400
|
+
if (this.selected === item.key) {
|
|
402
401
|
let nextKey: string | undefined;
|
|
403
402
|
if (this.items[index]) {
|
|
404
403
|
nextKey = this.items[index].key;
|
|
405
404
|
} else if (this.items[index - 1]) {
|
|
406
405
|
nextKey = this.items[index - 1].key;
|
|
407
406
|
} else if (this.items.length) {
|
|
408
|
-
const [
|
|
409
|
-
nextKey =
|
|
407
|
+
const [other] = this.items;
|
|
408
|
+
nextKey = other.key;
|
|
410
409
|
}
|
|
411
410
|
this.selected = nextKey;
|
|
412
411
|
}
|
|
412
|
+
|
|
413
413
|
if (!opts.noSideEffects) {
|
|
414
|
-
this.manager.notifyTabClose(key);
|
|
414
|
+
this.manager.notifyTabClose(item.key, this.key);
|
|
415
415
|
this.manager.notifyChange();
|
|
416
416
|
this.manager.updateView(this.key);
|
|
417
417
|
}
|
|
418
|
-
return
|
|
418
|
+
return item;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* Removes an item from the layout
|
|
423
|
+
* @param key The `key` of the item.
|
|
424
|
+
* @returns The removed item, if any.
|
|
425
|
+
*/
|
|
426
|
+
removeItem(key: string, opts?: SplitPanelRemoveItemOptions): SplitItem | undefined {
|
|
427
|
+
const removed = this.manager.findItem(key);
|
|
428
|
+
if (!removed) {
|
|
429
|
+
return undefined;
|
|
430
|
+
}
|
|
431
|
+
return this.removeChildItem(removed, opts);
|
|
432
|
+
// const index = this.items.findIndex(i => i.key === key);
|
|
433
|
+
// if (index < 0) {
|
|
434
|
+
// return undefined;
|
|
435
|
+
// }
|
|
436
|
+
// const itemInfo = this.items[index];
|
|
437
|
+
// this.items.splice(index, 1);
|
|
438
|
+
// this.manager.definitions.delete(itemInfo.key);
|
|
439
|
+
// this.decreaseIndex(removed.index || 0);
|
|
440
|
+
|
|
441
|
+
// if (this.items.length === 0) {
|
|
442
|
+
// // remove panel (self)
|
|
443
|
+
// const parent = this.getParent();
|
|
444
|
+
// if (parent) {
|
|
445
|
+
// parent.removePanel(this.key);
|
|
446
|
+
// // Note, ignore `opts.noSideEffects` for tab close. It won't get dispatched elsewhere.
|
|
447
|
+
// this.manager.notifyTabClose(key);
|
|
448
|
+
// // no point doing the stuff below as the whole panel is removed.
|
|
449
|
+
// return removed;
|
|
450
|
+
// }
|
|
451
|
+
// }
|
|
452
|
+
// if (this.selected === key) {
|
|
453
|
+
// let nextKey: string | undefined;
|
|
454
|
+
// if (this.items[index]) {
|
|
455
|
+
// nextKey = this.items[index].key;
|
|
456
|
+
// } else if (this.items[index - 1]) {
|
|
457
|
+
// nextKey = this.items[index - 1].key;
|
|
458
|
+
// } else if (this.items.length) {
|
|
459
|
+
// const [item] = this.items;
|
|
460
|
+
// nextKey = item.key;
|
|
461
|
+
// }
|
|
462
|
+
// this.selected = nextKey;
|
|
463
|
+
// }
|
|
464
|
+
// if (!opts.noSideEffects) {
|
|
465
|
+
// this.manager.notifyTabClose(key);
|
|
466
|
+
// this.manager.notifyChange();
|
|
467
|
+
// this.manager.updateView(this.key);
|
|
468
|
+
// }
|
|
469
|
+
// return removed;
|
|
419
470
|
}
|
|
420
471
|
|
|
421
472
|
/**
|
|
@@ -423,30 +474,30 @@ export class SplitPanel {
|
|
|
423
474
|
* @param dir The direction to which close other items. Default to both directions leaving only the `key` item
|
|
424
475
|
*/
|
|
425
476
|
removeRelative(key: string, dir: SplitCloseDirection = SplitCloseDirection.both): void {
|
|
426
|
-
const
|
|
477
|
+
const items = this.sortedItems();
|
|
478
|
+
const index = items.findIndex(i => i.key === key);
|
|
427
479
|
if (index < 0) {
|
|
428
480
|
return;
|
|
429
481
|
}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
let removed: IPanelObject[];
|
|
482
|
+
|
|
483
|
+
const item = items[index];
|
|
484
|
+
let removed: string[] = [];
|
|
434
485
|
if (dir === SplitCloseDirection.both) {
|
|
435
|
-
removed =
|
|
436
|
-
this.items = [item];
|
|
437
|
-
this.selected = item.key;
|
|
486
|
+
removed = items.filter(i => i !== item).map(i => i.key);
|
|
438
487
|
} else if (dir === SplitCloseDirection.left) {
|
|
439
|
-
removed =
|
|
440
|
-
this.items = this.items.splice(index);
|
|
441
|
-
this.selected = item.key;
|
|
488
|
+
removed = items.slice(0, index).map(i => i.key);
|
|
442
489
|
} else {
|
|
443
|
-
removed = this.items.slice(index + 1);
|
|
444
|
-
this.items = this.items.splice(0, index + 1);
|
|
445
|
-
this.selected = item.key;
|
|
490
|
+
removed = this.items.slice(index + 1).map(i => i.key);
|
|
446
491
|
}
|
|
492
|
+
this.items = this.items.filter(i => !removed.includes(i.key));
|
|
493
|
+
this.selected = item.key;
|
|
494
|
+
|
|
447
495
|
removed.forEach(i => {
|
|
448
|
-
this.manager.
|
|
449
|
-
|
|
496
|
+
const parents = this.manager.getParents(i);
|
|
497
|
+
if (!parents.length) {
|
|
498
|
+
this.manager.definitions.delete(i);
|
|
499
|
+
}
|
|
500
|
+
this.manager.notifyTabClose(i, this.key);
|
|
450
501
|
});
|
|
451
502
|
this.manager.notifyChange();
|
|
452
503
|
this.manager.updateView(this.key);
|
|
@@ -490,7 +541,7 @@ export class SplitPanel {
|
|
|
490
541
|
* @param key The item key
|
|
491
542
|
* @param toIndex The new index. When not set it moves the item to the end.
|
|
492
543
|
*/
|
|
493
|
-
moveItem(key: string,
|
|
544
|
+
moveItem(key: string, opts: SplitLayoutAddOptions = {}): void {
|
|
494
545
|
const info = this.items.find(i => i.key === key);
|
|
495
546
|
if (!info) {
|
|
496
547
|
return;
|
|
@@ -499,22 +550,54 @@ export class SplitPanel {
|
|
|
499
550
|
if (!item) {
|
|
500
551
|
return;
|
|
501
552
|
}
|
|
502
|
-
const
|
|
503
|
-
if (
|
|
553
|
+
const { index, region } = opts;
|
|
554
|
+
if (region) {
|
|
555
|
+
this.moveToRegion(item, region);
|
|
556
|
+
} else if (typeof index === 'number') {
|
|
557
|
+
this.moveToIndex(item, index);
|
|
558
|
+
} else {
|
|
559
|
+
this.moveToEnd(item);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
moveToRegion(item: SplitItem, region: SplitRegion): void {
|
|
564
|
+
if (this.items.length < 2) {
|
|
565
|
+
// nothing to split.
|
|
504
566
|
return;
|
|
505
567
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
568
|
+
if (region === SplitRegion.center) {
|
|
569
|
+
// the item is already there.
|
|
570
|
+
return;
|
|
509
571
|
}
|
|
510
|
-
|
|
511
|
-
|
|
572
|
+
const itemsIndex = this.items.findIndex(i => i.key === item.key);
|
|
573
|
+
if (itemsIndex < 0) {
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
this.items.splice(itemsIndex, 1);
|
|
577
|
+
const index = typeof item.index === 'number' ? item.index : this.nextIndex();
|
|
578
|
+
const panel = this.splitByRegion(region);
|
|
579
|
+
panel.addItem(item, { index });
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
moveToIndex(item: SplitItem, index: number): void {
|
|
583
|
+
if (item.index === index) {
|
|
584
|
+
return;
|
|
512
585
|
}
|
|
513
|
-
const
|
|
586
|
+
const hasTargetAtTarget = !!this.items[index as number];
|
|
587
|
+
this.decreaseIndex(item.index);
|
|
514
588
|
if (hasTargetAtTarget) {
|
|
515
|
-
this.increaseIndex(
|
|
589
|
+
this.increaseIndex(index);
|
|
590
|
+
}
|
|
591
|
+
item.index = index;
|
|
592
|
+
this.manager.notifyChange();
|
|
593
|
+
this.manager.updateView(this.key);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
moveToEnd(item: SplitItem): void {
|
|
597
|
+
if (item.index !== undefined) {
|
|
598
|
+
this.decreaseIndex(item.index);
|
|
516
599
|
}
|
|
517
|
-
item.index =
|
|
600
|
+
item.index = this.nextIndex();
|
|
518
601
|
this.manager.notifyChange();
|
|
519
602
|
this.manager.updateView(this.key);
|
|
520
603
|
}
|
|
@@ -70,7 +70,7 @@ export default class SplitView extends LitElement {
|
|
|
70
70
|
e.stopPropagation();
|
|
71
71
|
dataTransfer.dropEffect = 'copy';
|
|
72
72
|
}
|
|
73
|
-
|
|
73
|
+
|
|
74
74
|
protected handleDragOver(e: DragEvent): void {
|
|
75
75
|
const { dataTransfer } = e;
|
|
76
76
|
if (!dataTransfer || !this.panelCanDrop(e)) {
|
|
@@ -90,7 +90,8 @@ export default class SplitView extends LitElement {
|
|
|
90
90
|
|
|
91
91
|
protected handleDrop(e: DragEvent): void {
|
|
92
92
|
const { dataTransfer } = e;
|
|
93
|
-
|
|
93
|
+
const { panel } = this;
|
|
94
|
+
if (!dataTransfer || !panel || !this.panelCanDrop(e)) {
|
|
94
95
|
return;
|
|
95
96
|
}
|
|
96
97
|
e.preventDefault();
|
|
@@ -100,22 +101,23 @@ export default class SplitView extends LitElement {
|
|
|
100
101
|
if (!kind || !key) {
|
|
101
102
|
return;
|
|
102
103
|
}
|
|
104
|
+
const layoutKey = dataTransfer.getData('layout/key');
|
|
103
105
|
this.inDrag = false;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (
|
|
106
|
+
// TODO: When the drag originated in another panel then we
|
|
107
|
+
// move the panel between them. Otherwise we add the item to the panel.
|
|
108
|
+
if (layoutKey) {
|
|
109
|
+
// move operation not add.
|
|
110
|
+
panel.manager.moveItem(layoutKey, panel.key, key, { region: this.dragRegion });
|
|
111
|
+
} else {
|
|
107
112
|
panel.addItem({ key, kind, label: 'New tab' }, { region: this.dragRegion });
|
|
108
113
|
panel.manager.requestNameUpdate(key);
|
|
109
|
-
dispatch = true;
|
|
110
|
-
}
|
|
111
|
-
if (dispatch) {
|
|
112
|
-
this.dispatchEvent(new CustomEvent('datadrop', {
|
|
113
|
-
detail: { kind, key, region: this.dragRegion },
|
|
114
|
-
composed: true,
|
|
115
|
-
bubbles: true,
|
|
116
|
-
cancelable: true,
|
|
117
|
-
}));
|
|
118
114
|
}
|
|
115
|
+
this.dispatchEvent(new CustomEvent('datadrop', {
|
|
116
|
+
detail: { kind, key, region: this.dragRegion },
|
|
117
|
+
composed: true,
|
|
118
|
+
bubbles: true,
|
|
119
|
+
cancelable: true,
|
|
120
|
+
}));
|
|
119
121
|
this.requestUpdate();
|
|
120
122
|
}
|
|
121
123
|
|
|
@@ -282,7 +284,7 @@ export default class SplitView extends LitElement {
|
|
|
282
284
|
protected moveTab(fromLayout: string, toLayout: string, key: string, toIndex?: number): void {
|
|
283
285
|
const { panel } = this;
|
|
284
286
|
if (panel) {
|
|
285
|
-
panel.manager.moveItem(fromLayout, toLayout, key, toIndex);
|
|
287
|
+
panel.manager.moveItem(fromLayout, toLayout, key, { index: toIndex });
|
|
286
288
|
}
|
|
287
289
|
}
|
|
288
290
|
|
|
@@ -452,6 +454,7 @@ export default class SplitView extends LitElement {
|
|
|
452
454
|
data-index="${index}"
|
|
453
455
|
data-parent="${ifDefined(parent)}"
|
|
454
456
|
data-dirty="${isDirty}"
|
|
457
|
+
data-panel="${ifDefined(panel?.key)}"
|
|
455
458
|
role="tab"
|
|
456
459
|
class="${classMap(classes)}"
|
|
457
460
|
draggable="true"
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { ISplitLayout } from "./SplitLayout.js";
|
|
1
|
+
import type { TemplateResult } from "lit";
|
|
2
|
+
import type { SplitItem } from "./SplitItem.js";
|
|
3
|
+
import type { ISplitLayout } from "./SplitLayout.js";
|
|
5
4
|
|
|
6
5
|
export enum SplitDirection {
|
|
7
6
|
horizontal = 'horizontal',
|