Skip to content

Commit cfd7c7c

Browse files
authored
feat: develop auxiliary bar (#833)
* feat: develop auxiliary bar * fix: fix can't select in auxiliaryBar * test: update tests * chore: rename auxiliaryService to auxiliaryBarService * test: improve tests * test: improve tests * test: improve tests * test: remove console.log in test * test: update tests
1 parent 2cf87db commit cfd7c7c

File tree

36 files changed

+2199
-19
lines changed

36 files changed

+2199
-19
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { AuxiliaryBarService } from 'mo/services';
2+
import { container } from 'tsyringe';
3+
import { AuxiliaryController } from '..';
4+
5+
const auxiliaryBarController = container.resolve(AuxiliaryController);
6+
const auxiliaryBarService = container.resolve(AuxiliaryBarService);
7+
8+
describe('The AuxiliaryBar Controller', () => {
9+
test('Should support call onClick', () => {
10+
const original = auxiliaryBarService.setActive;
11+
auxiliaryBarService.setActive = jest.fn((props) => original(props));
12+
13+
const clickFn = jest.fn();
14+
auxiliaryBarService.onTabClick(clickFn);
15+
16+
auxiliaryBarController.onClick(1);
17+
expect(auxiliaryBarService.setActive).toBeCalledWith(1);
18+
expect(clickFn).toBeCalledWith(1);
19+
20+
auxiliaryBarController.onClick(1);
21+
expect(auxiliaryBarService.setActive).toBeCalledWith(undefined);
22+
expect(clickFn).toBeCalledWith(1);
23+
24+
auxiliaryBarService.setActive = original;
25+
});
26+
});

src/controller/__tests__/menuBar.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,19 @@ describe('The menuBar controller', () => {
140140
expect(mockExecute.mock.calls[1][1]).toEqual({ icon: 'check' });
141141
mockExecute.mockClear();
142142

143+
// update auxiliary bar
144+
mockItem.id = constants.MENU_VIEW_AUXILIARY;
145+
menuBarController.onClick(mockEvent, mockItem);
146+
expect(mockExecute).toBeCalled();
147+
expect(mockExecute.mock.calls[0][0]).toBe(
148+
constants.MENU_VIEW_AUXILIARY
149+
);
150+
expect(mockExecute.mock.calls[0][1]).toEqual({ icon: 'check' });
151+
152+
menuBarController.onClick(mockEvent, mockItem);
153+
expect(mockExecute.mock.calls[1][1]).toEqual({ icon: '' });
154+
mockExecute.mockClear();
155+
143156
// update menu bar
144157
mockItem.id = constants.MENU_VIEW_MENUBAR;
145158
menuBarController.onClick(mockEvent, mockItem);

src/controller/auxiliaryBar.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import 'reflect-metadata';
2+
import { Controller } from 'mo/react/controller';
3+
import { container, singleton } from 'tsyringe';
4+
import { AuxiliaryBarService, IAuxiliaryBarService } from 'mo/services';
5+
import { AuxiliaryEventKind } from 'mo/model';
6+
import type { UniqueId } from 'mo/common/types';
7+
8+
export interface IAuxiliaryController {
9+
onClick?: (key: UniqueId) => void;
10+
}
11+
12+
@singleton()
13+
export class AuxiliaryController
14+
extends Controller
15+
implements IAuxiliaryController
16+
{
17+
private readonly auxiliaryService: IAuxiliaryBarService;
18+
constructor() {
19+
super();
20+
this.auxiliaryService = container.resolve(AuxiliaryBarService);
21+
}
22+
23+
public initView = () => {};
24+
25+
public onClick = (key: UniqueId) => {
26+
this.auxiliaryService.setActive(
27+
this.auxiliaryService.getState().current === key ? undefined : key
28+
);
29+
this.emit(AuxiliaryEventKind.onTabClick, key);
30+
};
31+
}

src/controller/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * from './activityBar';
2+
export * from './auxiliaryBar';
23
export * from './editor';
34
export * from './menuBar';
45
export * from './notification';

src/controller/menuBar.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export class MenuBarController
6767
ACTION_QUICK_SELECT_ALL,
6868
ACTION_QUICK_COPY_LINE_UP,
6969
MENU_VIEW_ACTIVITYBAR,
70+
MENU_VIEW_AUXILIARY,
7071
MENU_VIEW_MENUBAR,
7172
MENU_VIEW_STATUSBAR,
7273
MENU_QUICK_COMMAND,
@@ -94,6 +95,7 @@ export class MenuBarController
9495
[MENU_VIEW_STATUSBAR, () => this.updateStatusBar()],
9596
[MENU_QUICK_COMMAND, () => this.gotoQuickCommand()],
9697
[ID_SIDE_BAR, () => this.updateSideBar()],
98+
[MENU_VIEW_AUXILIARY, () => this.updateAuxiliaryBar()],
9799
[MENU_VIEW_PANEL, () => this.updatePanel()],
98100
[
99101
MENUBAR_MODE_HORIZONTAL,
@@ -264,6 +266,19 @@ export class MenuBarController
264266
);
265267
};
266268

269+
public updateAuxiliaryBar = () => {
270+
const nextHidden = this.layoutService.setAuxiliaryBar(
271+
(hidden) => !hidden
272+
);
273+
274+
const { MENU_VIEW_AUXILIARY } = this.builtinService.getConstants();
275+
if (MENU_VIEW_AUXILIARY) {
276+
this.menuBarService.update(MENU_VIEW_AUXILIARY, {
277+
icon: nextHidden ? '' : 'check',
278+
});
279+
}
280+
};
281+
267282
private updatePanel = () => {
268283
this.monacoService.commandService.executeCommand(
269284
QuickTogglePanelAction.ID

src/extensions/locales-defaults/locales/en.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"menu.openView": "Open View",
2323
"menu.appearance": "Appearance",
2424
"menu.showMenuBar": "Show Menu Bar",
25-
"menu.showSideBar": "Show Side bar",
25+
"menu.showAuxiliaryBar": "Show Auxiliary Bar",
26+
"menu.showSideBar": "Show Side Bar",
2627
"menu.showSideBar.label": "Toggle Side Bar Visibility",
2728
"menu.showStatusBar": "Show Status Bar",
2829
"menu.showActivityBar": "Show Activity Bar",

src/extensions/locales-defaults/locales/zh-CN.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"menu.openView": "打开视图",
2323
"menu.appearance": "外观",
2424
"menu.showMenuBar": "显示菜单栏",
25-
"menu.showSideBar": "显示边栏",
25+
"menu.showAuxiliaryBar": "显示辅助侧边栏",
26+
"menu.showSideBar": "显示侧边栏",
2627
"menu.showSideBar.label": "切换侧边栏",
2728
"menu.showStatusBar": "显示状态栏",
2829
"menu.showActivityBar": "显示活动栏",
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import type { UniqueId } from 'mo/common/types';
3+
4+
export enum AuxiliaryEventKind {
5+
onTabClick = 'AuxiliaryBar.onClick',
6+
}
7+
8+
export type IAuxiliaryBarMode = 'default' | 'tabs';
9+
10+
export type IAuxiliaryData = { key: UniqueId; title: React.ReactNode };
11+
12+
export interface IAuxiliaryBar {
13+
mode: IAuxiliaryBarMode;
14+
data: IAuxiliaryData[];
15+
current?: UniqueId;
16+
children?: React.ReactNode;
17+
}
18+
19+
export class AuxiliaryModel implements IAuxiliaryBar {
20+
public mode: IAuxiliaryBarMode = 'default';
21+
public children: React.ReactNode;
22+
public data: IAuxiliaryData[] = [];
23+
public current?: UniqueId;
24+
constructor(
25+
mode: IAuxiliaryBarMode = 'default',
26+
data: IAuxiliaryData[] = [],
27+
current?: UniqueId,
28+
children?: React.ReactNode
29+
) {
30+
this.mode = mode;
31+
this.children = children;
32+
this.data = data;
33+
this.current = current;
34+
}
35+
}

src/model/workbench/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { IActivityBar, IMenuBar, IPanel, ISidebar, IStatusBar } from 'mo/model';
22

33
export * from './activityBar';
4+
export * from './auxiliaryBar';
45
export * from './editor';
56
export * from './sidebar';
67
export * from './statusBar';

src/model/workbench/layout.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ export interface ILayout {
2727
splitPanePos: (number | string)[];
2828
horizontalSplitPanePos: (number | string)[];
2929
activityBar: ViewVisibility;
30+
auxiliaryBar: ViewVisibility;
3031
panel: IPanelViewState;
3132
statusBar: ViewVisibility;
3233
sidebar: ISidebarViewState;
@@ -40,16 +41,18 @@ export class LayoutModel implements ILayout {
4041
public horizontalSplitPanePos: (number | string)[];
4142
public groupSplitPos: (number | string)[];
4243
public activityBar: ViewVisibility;
44+
public auxiliaryBar: ViewVisibility;
4345
public panel: IPanelViewState;
4446
public statusBar: ViewVisibility;
4547
public sidebar: ISidebarViewState;
4648
public menuBar: IMenuBarViewState;
4749
public editorGroupDirection: MenuBarMode;
4850
constructor(
49-
splitPanePos: string[] = ['300px', 'auto'],
51+
splitPanePos: (number | string)[] = [300, 'auto', 300],
5052
horizontalSplitPanePos = ['auto', '150px'],
5153
groupSplitPos = [],
5254
activityBar = { hidden: false },
55+
auxiliaryBar = { hidden: true },
5356
panel = { hidden: false, panelMaximized: false },
5457
statusBar = { hidden: false },
5558
sidebar = { hidden: false, position: Position.left },
@@ -60,6 +63,7 @@ export class LayoutModel implements ILayout {
6063
this.horizontalSplitPanePos = horizontalSplitPanePos;
6164
this.groupSplitPos = groupSplitPos;
6265
this.activityBar = activityBar;
66+
this.auxiliaryBar = auxiliaryBar;
6367
this.panel = panel;
6468
this.statusBar = statusBar;
6569
this.sidebar = sidebar;

0 commit comments

Comments
 (0)