feat(tabs): add close tabs to the left action

This commit is contained in:
guoziyangnb authored and GitHub committed 2026-08-31 23:46:03 +08:00
1 parent 40a806a24a
commit 662037295c
11 files changed
+67

No files matched your search

@@ -209,6 +209,20 @@ function closeTabsToRightFromTab(tab: QueryTab) {
});
}
function tabsToLeftInGroup(tab: QueryTab) {
const groupedTabs = tab.pinned ? fixedTabs.value : regularTabs.value;
const targetIndex = groupedTabs.findIndex((item) => item.id === tab.id);
return targetIndex < 0 ? [] : groupedTabs.slice(0, targetIndex);
}
function hasTabsToLeft(tab: QueryTab) {
return tabsToLeftInGroup(tab).length > 0;
}
function closeTabsToLeftFromTab(tab: QueryTab) {
queryStore.closeLeftTabs(tab.id);
}
function hasSpecialRegularSurfaceToRight(surface: SpecialRegularSurface) {
return surface === "settings" && !!props.driverStoreOpen;
}
@@ -345,6 +359,12 @@ function getTabMenuItems(tab: QueryTab): ContextMenuItem[] {
icon: X,
shortcut: settingsStore.editorSettings.shortcuts.closeOtherTabs,
},
{
label: t("contextMenu.closeLeftTabs"),
action: () => closeTabsToLeftFromTab(tab),
disabled: !hasTabsToLeft(tab),
icon: X,
},
{
label: t("contextMenu.closeRightTabs"),
action: () => closeTabsToRightFromTab(tab),
@@ -108,6 +108,27 @@ describe("AppTabBar right-side close action", () => {
});
});
describe("AppTabBar left-side close action", () => {
it("places the action after close-other, before close-right, and disables it when the target has no tabs to its left", () => {
expect(tabBarSource).toContain('label: t("contextMenu.closeLeftTabs")');
expect(tabBarSource).toContain("action: () => closeTabsToLeftFromTab(tab)");
expect(tabBarSource).toContain("disabled: !hasTabsToLeft(tab)");
const closeOtherPositions = [...tabBarSource.matchAll(/label: closeOtherLabel,/g)].map((match) => match.index);
const closeLeftPositions = [...tabBarSource.matchAll(/label: t\("contextMenu\.closeLeftTabs"\),/g)].map((match) => match.index);
const closeRightPositions = [...tabBarSource.matchAll(/label: t\("contextMenu\.closeRightTabs"\),/g)].map((match) => match.index);
expect(closeOtherPositions).toHaveLength(2);
// The special-surface menu has no left-side action: settings and the
// driver store sit at the rightmost end of the tab bar, so nothing can be
// to the left of them. Only the regular/pinned tab menu gets the item.
expect(closeLeftPositions).toHaveLength(1);
expect(closeRightPositions).toHaveLength(2);
const closeLeftPosition = closeLeftPositions[0];
expect(closeLeftPosition).toBeGreaterThan(closeOtherPositions[1]);
expect(closeLeftPosition).toBeLessThan(closeRightPositions[1]);
});
});
describe("AppTabBar special page selection", () => {
it("shows the active settings or driver-manager tab with the same ring used by regular tabs", () => {
expect(tabBarSource).toContain("function specialTabActiveStyle(active: boolean | undefined)");