@opensumi/ide-main-layout 3.9.1-next-1749181695.0 → 3.9.1-next-1749196667.0

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 (71) hide show
  1. package/README.md +31 -30
  2. package/lib/browser/accordion/accordion.service.d.ts +1 -9
  3. package/lib/browser/accordion/accordion.service.d.ts.map +1 -1
  4. package/lib/browser/accordion/accordion.service.js +33 -120
  5. package/lib/browser/accordion/accordion.service.js.map +1 -1
  6. package/lib/browser/accordion/accordion.view.d.ts.map +1 -1
  7. package/lib/browser/accordion/accordion.view.js +1 -4
  8. package/lib/browser/accordion/accordion.view.js.map +1 -1
  9. package/lib/browser/accordion/section.view.d.ts.map +1 -1
  10. package/lib/browser/accordion/section.view.js +1 -1
  11. package/lib/browser/accordion/section.view.js.map +1 -1
  12. package/lib/browser/accordion/styles.module.less +0 -61
  13. package/lib/browser/default-config.d.ts.map +1 -1
  14. package/lib/browser/default-config.js +6 -7
  15. package/lib/browser/default-config.js.map +1 -1
  16. package/lib/browser/drop-area/drop-area.d.ts +2 -3
  17. package/lib/browser/drop-area/drop-area.d.ts.map +1 -1
  18. package/lib/browser/drop-area/drop-area.js +5 -8
  19. package/lib/browser/drop-area/drop-area.js.map +1 -1
  20. package/lib/browser/index.d.ts.map +1 -1
  21. package/lib/browser/index.js.map +1 -1
  22. package/lib/browser/layout.service.d.ts +0 -4
  23. package/lib/browser/layout.service.d.ts.map +1 -1
  24. package/lib/browser/layout.service.js +79 -140
  25. package/lib/browser/layout.service.js.map +1 -1
  26. package/lib/browser/main-layout.contribution.d.ts +18 -2
  27. package/lib/browser/main-layout.contribution.d.ts.map +1 -1
  28. package/lib/browser/main-layout.contribution.js +131 -75
  29. package/lib/browser/main-layout.contribution.js.map +1 -1
  30. package/lib/browser/tabbar/bar.view.d.ts.map +1 -1
  31. package/lib/browser/tabbar/bar.view.js +10 -5
  32. package/lib/browser/tabbar/bar.view.js.map +1 -1
  33. package/lib/browser/tabbar/panel.view.js +2 -2
  34. package/lib/browser/tabbar/panel.view.js.map +1 -1
  35. package/lib/browser/tabbar/renderer.view.js +4 -4
  36. package/lib/browser/tabbar/renderer.view.js.map +1 -1
  37. package/lib/browser/tabbar/tabbar.service.d.ts +19 -8
  38. package/lib/browser/tabbar/tabbar.service.d.ts.map +1 -1
  39. package/lib/browser/tabbar/tabbar.service.js +148 -39
  40. package/lib/browser/tabbar/tabbar.service.js.map +1 -1
  41. package/lib/common/main-layout.definition.d.ts +3 -4
  42. package/lib/common/main-layout.definition.d.ts.map +1 -1
  43. package/lib/common/main-layout.definition.js +4 -5
  44. package/lib/common/main-layout.definition.js.map +1 -1
  45. package/package.json +8 -8
  46. package/src/browser/accordion/accordion.service.ts +35 -152
  47. package/src/browser/accordion/accordion.view.tsx +2 -4
  48. package/src/browser/accordion/section.view.tsx +1 -5
  49. package/src/browser/accordion/styles.module.less +0 -61
  50. package/src/browser/default-config.ts +7 -8
  51. package/src/browser/drop-area/drop-area.tsx +3 -6
  52. package/src/browser/index.ts +0 -1
  53. package/src/browser/layout.service.ts +67 -156
  54. package/src/browser/main-layout.contribution.ts +138 -93
  55. package/src/browser/tabbar/bar.view.tsx +14 -9
  56. package/src/browser/tabbar/panel.view.tsx +2 -2
  57. package/src/browser/tabbar/renderer.view.tsx +4 -4
  58. package/src/browser/tabbar/tabbar.service.ts +163 -54
  59. package/src/common/main-layout.definition.ts +4 -6
  60. package/lib/browser/command.d.ts +0 -29
  61. package/lib/browser/command.d.ts.map +0 -1
  62. package/lib/browser/command.js +0 -84
  63. package/lib/browser/command.js.map +0 -1
  64. package/lib/browser/tabbar/TABBAR_CONFIG_USAGE.md +0 -141
  65. package/lib/browser/tabbar/tabbar-behavior-handler.d.ts +0 -71
  66. package/lib/browser/tabbar/tabbar-behavior-handler.d.ts.map +0 -1
  67. package/lib/browser/tabbar/tabbar-behavior-handler.js +0 -210
  68. package/lib/browser/tabbar/tabbar-behavior-handler.js.map +0 -1
  69. package/src/browser/command.ts +0 -99
  70. package/src/browser/tabbar/TABBAR_CONFIG_USAGE.md +0 -141
  71. package/src/browser/tabbar/tabbar-behavior-handler.ts +0 -260
@@ -18,7 +18,7 @@ import {
18
18
  WithEventBus,
19
19
  slotRendererRegistry,
20
20
  } from '@opensumi/ide-core-browser';
21
- import { Layout, fixLayout } from '@opensumi/ide-core-browser/lib/components';
21
+ import { fixLayout } from '@opensumi/ide-core-browser/lib/components';
22
22
  import { LAYOUT_STATE, LayoutState } from '@opensumi/ide-core-browser/lib/layout/layout-state';
23
23
  import { ComponentRegistryInfo } from '@opensumi/ide-core-browser/lib/layout/layout.interface';
24
24
  import {
@@ -29,13 +29,11 @@ import {
29
29
  MenuId,
30
30
  } from '@opensumi/ide-core-browser/lib/menu/next';
31
31
  import { Deferred, getDebugLogger, isUndefined } from '@opensumi/ide-core-common';
32
- import { transaction } from '@opensumi/ide-monaco/lib/common/observable';
33
32
  import { ThemeChangedEvent } from '@opensumi/ide-theme';
34
33
 
35
34
  import {
36
- DROP_EXTEND_VIEW_CONTAINER,
37
- DROP_PANEL_CONTAINER,
38
- DROP_VIEW_CONTAINER,
35
+ DROP_BOTTOM_CONTAINER,
36
+ DROP_RIGHT_CONTAINER,
39
37
  IMainLayoutService,
40
38
  MainLayoutContribution,
41
39
  SUPPORT_ACCORDION_LOCATION,
@@ -47,21 +45,19 @@ import { TabbarService } from './tabbar/tabbar.service';
47
45
  import { TabBarHandler } from './tabbar-handler';
48
46
 
49
47
  const defaultLayoutState = {
50
- [SlotLocation.view]: {
48
+ [SlotLocation.left]: {
51
49
  currentId: undefined,
52
50
  size: undefined,
53
51
  },
54
- [SlotLocation.extendView]: {
52
+ [SlotLocation.right]: {
55
53
  // 依照下面的恢复逻辑,这里设置为 `''` 时,就不会恢复右侧的 TabBar 的状态(即选中相应的 viewContainer)
56
54
  currentId: '',
57
55
  size: undefined,
58
56
  },
59
- [SlotLocation.panel]: {
57
+ [SlotLocation.bottom]: {
60
58
  currentId: undefined,
61
59
  size: undefined,
62
60
  },
63
- // 存储 Container 的移动信息:containerId -> location
64
- containerLocations: {},
65
61
  };
66
62
 
67
63
  @Injectable()
@@ -115,9 +111,6 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
115
111
  };
116
112
  } = {};
117
113
 
118
- // 记录正在恢复状态的 location,防止恢复过程中存储中间状态
119
- private isRestoring = new Set<string>();
120
-
121
114
  private customViews = new Map<string, View>();
122
115
 
123
116
  private debug = getDebugLogger();
@@ -157,16 +150,10 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
157
150
  }
158
151
 
159
152
  storeState(service: TabbarService, currentId?: string) {
160
- // 如果正在恢复中,跳过存储,避免存储中间状态
161
- if (this.isRestoring.has(service.location)) {
162
- return;
163
- }
164
-
165
153
  this.state[service.location] = {
166
154
  currentId,
167
155
  size: service.prevSize,
168
156
  };
169
-
170
157
  this.layoutState.setState(LAYOUT_STATE.MAIN, this.state);
171
158
  }
172
159
 
@@ -187,89 +174,63 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
187
174
 
188
175
  restoreTabbarService = async (service: TabbarService) => {
189
176
  this.state = fixLayout(this.layoutState.getState(LAYOUT_STATE.MAIN, defaultLayoutState));
177
+
190
178
  const { currentId, size } = this.state[service.location] || {};
191
179
  service.prevSize = size;
192
-
193
- // 根据存储的容器位置信息恢复容器位置(drag & drop 移动过的)
194
- if (this.state.containerLocations) {
195
- for (const [containerId, targetLocation] of Object.entries(this.state.containerLocations)) {
196
- if (targetLocation === service.location && !this.isDropContainer(containerId)) {
197
- // 检查容器是否在其他 tabbar 中,如果是则移动到当前 tabbar
198
- const expectTabbar = this.findTabbarServiceByContainerId(containerId);
199
- if (expectTabbar && expectTabbar.location !== service.location) {
200
- this.moveContainerTo(containerId, service.location);
180
+ let defaultContainer = service.visibleContainers[0] && service.visibleContainers[0].options!.containerId;
181
+ const defaultPanels = this.appConfig.defaultPanels;
182
+ const restorePanel = defaultPanels && defaultPanels[service.location];
183
+ if (defaultPanels && restorePanel !== undefined) {
184
+ if (restorePanel) {
185
+ if (service.containersMap.has(restorePanel)) {
186
+ defaultContainer = restorePanel;
187
+ } else {
188
+ const componentInfo = this.componentRegistry.getComponentRegistryInfo(restorePanel);
189
+ if (
190
+ componentInfo &&
191
+ this.appConfig.layoutConfig[service.location]?.modules &&
192
+ ~this.appConfig.layoutConfig[service.location].modules.indexOf(restorePanel)
193
+ ) {
194
+ defaultContainer = componentInfo.options!.containerId;
201
195
  } else {
202
- // 清理无用的状态
203
- delete this.state.containerLocations[containerId];
204
- this.layoutState.setState(LAYOUT_STATE.MAIN, this.state);
196
+ this.logger.warn(`[defaultPanels] No \`${restorePanel}\` view found!`);
205
197
  }
206
198
  }
199
+ } else {
200
+ defaultContainer = '';
207
201
  }
208
202
  }
209
-
210
- const defaultContainer = this.getDefaultContainer(service);
211
- this.restoreContainerId(service, currentId, defaultContainer);
212
- };
213
-
214
- private getDefaultContainer(service: TabbarService): string | undefined {
215
- const defaultPanels = this.appConfig.defaultPanels;
216
- const defaultPanel = defaultPanels && defaultPanels[service.location];
217
-
218
- // 如果配置了默认面板,则使用配置的面板
219
- if (defaultPanels && defaultPanel !== undefined) {
220
- if (!defaultPanel) {
221
- return '';
222
- }
223
- if (service.containersMap.has(defaultPanel)) {
224
- return defaultPanel;
225
- }
226
-
227
- const componentInfo = this.componentRegistry.getComponentRegistryInfo(defaultPanel);
228
- const isValidModule =
229
- componentInfo && this.appConfig.layoutConfig[service.location]?.modules?.includes(defaultPanel);
230
-
231
- if (isValidModule) {
232
- return componentInfo.options!.containerId;
233
- }
234
-
235
- this.logger.warn(`[defaultPanels] No \`${defaultPanel}\` view found!`);
236
- }
237
-
238
- // 获取第一个可见容器作为默认值
239
- return service.visibleContainers[0]?.options?.containerId;
240
- }
241
-
242
- private restoreContainerId(
243
- service: TabbarService,
244
- currentId: string | undefined,
245
- defaultContainer: string | undefined,
246
- ) {
203
+ /**
204
+ * ContainerId 存在三种值类型,对应的处理模式如下:
205
+ * 1. undefined: 采用首个注册的容器作为当前 containerId
206
+ * 2. string: 非 drop container 直接使用该 containerId 作为当前 containerId
207
+ * 3. '': 直接清空当前 containerId,不展开相应的 viewContainer
208
+ */
247
209
  if (isUndefined(currentId)) {
248
- // 未指定 currentId 时,使用默认容器或第一个注册的容器
249
210
  if (isUndefined(defaultContainer)) {
211
+ // 默认采用首个注册的容器作为当前 containerId
250
212
  service.updateNextContainerId();
251
213
  } else {
252
214
  service.updateCurrentContainerId(defaultContainer);
253
215
  }
254
- return;
255
- }
256
-
257
- if (currentId && !this.isDropContainer(currentId)) {
216
+ } else if (currentId && !this.isDropContainer(currentId)) {
258
217
  if (service.containersMap.has(currentId)) {
259
218
  service.updateCurrentContainerId(currentId);
260
- return;
219
+ } else {
220
+ // 如果在别的 tabbar 中存在该 containerId,则将其移动到当前 tabbar
221
+ if (this.findTabbarServiceByContainerId(currentId)) {
222
+ this.moveContainerTo(currentId, service.location);
223
+ service.updateCurrentContainerId(currentId);
224
+ } else {
225
+ service.updateCurrentContainerId(defaultContainer);
226
+ // 等待后续新容器注册时,更新当前的 containerId
227
+ service.updateNextContainerId(currentId);
228
+ }
261
229
  }
262
-
263
- // 如果当前 containerId 不存在,则使用默认容器
264
- service.updateCurrentContainerId(defaultContainer || '');
265
- service.updateNextContainerId(currentId);
266
- return;
267
- }
268
-
269
- if (currentId === '' || this.isDropContainer(currentId)) {
230
+ } else if (currentId === '' || this.isDropContainer(currentId)) {
270
231
  service.updateCurrentContainerId('');
271
232
  }
272
- }
233
+ };
273
234
 
274
235
  findTabbarServiceByContainerId(containerId: string): TabbarService | undefined {
275
236
  let tabbarService: undefined | TabbarService;
@@ -295,7 +256,7 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
295
256
  this.logger.error(`cannot find container: ${containerId}`);
296
257
  return;
297
258
  }
298
- if (container.options?.draggable === false) {
259
+ if (!container.options?.draggable) {
299
260
  this.logger.warn(`container: ${containerId} is not draggable`);
300
261
  return;
301
262
  }
@@ -310,59 +271,33 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
310
271
  toTabbar.dynamicAddContainer(containerId, container);
311
272
  const newHandler = this.injector.get(TabBarHandler, [containerId, this.getTabbarService(toTabbar.location)]);
312
273
  this.handleMap.set(containerId, newHandler!);
313
-
314
- // 更新容器位置信息
315
- if (!this.state.containerLocations) {
316
- this.state.containerLocations = {};
317
- }
318
- this.state.containerLocations[containerId] = to;
319
- // this.layoutState.setState(LAYOUT_STATE.MAIN, this.state);
320
274
  }
321
275
 
322
276
  showDropAreaForContainer(containerId: string): void {
323
277
  const tabbarService = this.findTabbarServiceByContainerId(containerId);
324
- const panelService = this.tabbarServices.get(SlotLocation.panel);
325
- const extendViewService = this.tabbarServices.get(SlotLocation.extendView);
326
- const viewService = this.tabbarServices.get(SlotLocation.view);
278
+ const bottomService = this.tabbarServices.get('bottom');
279
+ const rightService = this.tabbarServices.get('right');
327
280
  if (!tabbarService) {
328
281
  this.logger.error(`cannot find container: ${containerId}`);
329
282
  return;
330
283
  }
331
- const otherServices = {
332
- [SlotLocation.extendView]: [panelService, viewService],
333
- [SlotLocation.panel]: [extendViewService, viewService],
334
- [SlotLocation.view]: [panelService, extendViewService],
335
- };
336
-
337
- const dropContainers = {
338
- [SlotLocation.panel]: DROP_PANEL_CONTAINER,
339
- [SlotLocation.extendView]: DROP_EXTEND_VIEW_CONTAINER,
340
- [SlotLocation.view]: DROP_VIEW_CONTAINER,
341
- };
342
-
343
- transaction((tx) => {
344
- otherServices[tabbarService?.location]?.forEach((service) => {
345
- service?.updateCurrentContainerId(dropContainers[service?.location], tx);
346
- });
347
- });
284
+ if (tabbarService?.location === 'right') {
285
+ bottomService?.updateCurrentContainerId(DROP_BOTTOM_CONTAINER);
286
+ }
287
+ if (tabbarService?.location === 'bottom') {
288
+ rightService?.updateCurrentContainerId(DROP_RIGHT_CONTAINER);
289
+ }
348
290
  }
349
291
 
350
292
  hideDropArea(): void {
351
- const panelService = this.tabbarServices.get(SlotLocation.panel);
352
- const extendViewService = this.tabbarServices.get(SlotLocation.extendView);
353
- const viewService = this.tabbarServices.get(SlotLocation.view);
354
-
355
- transaction((tx) => {
356
- if (panelService?.currentContainerId.get() === DROP_PANEL_CONTAINER) {
357
- panelService.updateCurrentContainerId(panelService.previousContainerId || '', tx);
358
- }
359
- if (extendViewService?.currentContainerId.get() === DROP_EXTEND_VIEW_CONTAINER) {
360
- extendViewService.updateCurrentContainerId(extendViewService.previousContainerId || '', tx);
361
- }
362
- if (viewService?.currentContainerId.get() === DROP_VIEW_CONTAINER) {
363
- viewService.updateCurrentContainerId(viewService.previousContainerId || '', tx);
364
- }
365
- });
293
+ const bottomService = this.tabbarServices.get('bottom');
294
+ const rightService = this.tabbarServices.get('right');
295
+ if (bottomService?.currentContainerId.get() === DROP_BOTTOM_CONTAINER) {
296
+ bottomService.updateCurrentContainerId(bottomService.previousContainerId || '');
297
+ }
298
+ if (rightService?.currentContainerId.get() === DROP_RIGHT_CONTAINER) {
299
+ rightService.updateCurrentContainerId(rightService.previousContainerId || '');
300
+ }
366
301
  }
367
302
 
368
303
  isVisible(location: string) {
@@ -401,7 +336,7 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
401
336
  }
402
337
 
403
338
  private isDropContainer(containerId: string): boolean {
404
- return [DROP_PANEL_CONTAINER, DROP_EXTEND_VIEW_CONTAINER, DROP_VIEW_CONTAINER].includes(containerId);
339
+ return [DROP_BOTTOM_CONTAINER, DROP_RIGHT_CONTAINER].includes(containerId);
405
340
  }
406
341
 
407
342
  private findNonDropContainerId(tabbarService: TabbarService): string {
@@ -440,24 +375,14 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
440
375
  }),
441
376
  );
442
377
  service.viewReady.promise
443
- .then(() => {
444
- // 标记开始恢复,防止恢复过程中存储中间状态
445
- this.isRestoring.add(service.location);
446
- return service.restoreState();
447
- })
378
+ .then(() => service.restoreState())
448
379
  .then(() => this.restoreTabbarService(service))
449
- .then(() => {
450
- // 恢复完成,清除标记
451
- this.isRestoring.delete(service.location);
452
- })
453
380
  .catch((err) => {
454
- // 出错时也要清除标记
455
- this.isRestoring.delete(service.location);
456
381
  this.logger.error(`[TabbarService:${location}] restore state error`, err);
457
382
  });
458
383
  const debouncedStoreState = debounce(() => this.storeState(service, service.currentContainerId.get()), 100);
459
384
  service.addDispose(service.onSizeChange(debouncedStoreState));
460
- if (location === SlotLocation.panel) {
385
+ if (location === SlotLocation.bottom) {
461
386
  // use this getter's side effect to set bottomExpanded contextKey
462
387
  const debouncedUpdate = debounce(() => void this.bottomExpanded, 100);
463
388
  service.addDispose(service.onSizeChange(() => debouncedUpdate));
@@ -538,7 +463,6 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
538
463
  if (Fc) {
539
464
  this.debug.warn('collectTabbarComponent api warning: Please move react component into options.component!');
540
465
  }
541
- side = this.mapSideToLocation(side);
542
466
  if (options.hideIfEmpty && !views.length && !options.component) {
543
467
  this.holdTabbarComponent.set(options.containerId, { views, options, side });
544
468
  if (this.tabbarUpdateSet.has(options.containerId)) {
@@ -571,19 +495,6 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
571
495
  return options.containerId;
572
496
  }
573
497
 
574
- private mapSideToLocation(side: string): SlotLocation {
575
- switch (side) {
576
- case 'left':
577
- return SlotLocation.view;
578
- case 'right':
579
- return SlotLocation.extendView;
580
- case 'bottom':
581
- return SlotLocation.panel;
582
- default:
583
- return side;
584
- }
585
- }
586
-
587
498
  getViewAccordionService(viewId: string) {
588
499
  const containerId = this.viewToContainerMap.get(viewId);
589
500
  if (!containerId) {
@@ -729,7 +640,7 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
729
640
 
730
641
  // TODO 这样很耦合,不能做到tab renderer自由拆分
731
642
  expandBottom(expand: boolean): void {
732
- const tabbarService = this.getTabbarService(SlotLocation.panel);
643
+ const tabbarService = this.getTabbarService(SlotLocation.bottom);
733
644
  if (!tabbarService.currentContainerId.get()) {
734
645
  tabbarService.updateCurrentContainerId(
735
646
  tabbarService.currentContainerId.get() ||
@@ -742,7 +653,7 @@ export class LayoutService extends WithEventBus implements IMainLayoutService {
742
653
  }
743
654
 
744
655
  get bottomExpanded(): boolean {
745
- const tabbarService = this.getTabbarService(SlotLocation.panel);
656
+ const tabbarService = this.getTabbarService(SlotLocation.bottom);
746
657
  this.contextKeyService.createKey('bottomFullExpanded', tabbarService.isExpanded);
747
658
  return tabbarService.isExpanded;
748
659
  }