Skip to content

Commit 94c4bee

Browse files
committed
Add menu item to close all other tabs
1 parent b42ce5e commit 94c4bee

File tree

4 files changed

+60
-1
lines changed

4 files changed

+60
-1
lines changed

packages/compass-components/src/components/workspace-tabs/tab.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ export type WorkspaceTabCoreProps = {
194194
isDragging: boolean;
195195
onSelect: () => void;
196196
onClose: () => void;
197+
onCloseAllOthers: () => void;
197198
tabContentId: string;
198199
};
199200

@@ -209,6 +210,7 @@ function Tab({
209210
isDragging,
210211
onSelect,
211212
onClose,
213+
onCloseAllOthers,
212214
tabContentId,
213215
iconGlyph,
214216
className: tabClassName,
@@ -235,7 +237,10 @@ function Tab({
235237
return css(tabTheme);
236238
}, [tabTheme, darkMode]);
237239

238-
const contextMenuRef = useContextMenuItems(() => [], []);
240+
const contextMenuRef = useContextMenuItems(
241+
() => [{ label: 'Close all other tabs', onAction: onCloseAllOthers }],
242+
[onCloseAllOthers]
243+
);
239244

240245
const mergedRef = useMergeRefs([setNodeRef, contextMenuRef]);
241246

packages/compass-components/src/components/workspace-tabs/workspace-tabs.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ type SortableItemProps = {
151151
activeId: UniqueIdentifier | null;
152152
onSelect: (tabIndex: number) => void;
153153
onClose: (tabIndex: number) => void;
154+
onCloseAllOthers: (tabIndex: number) => void;
154155
};
155156

156157
type SortableListProps = {
@@ -159,6 +160,7 @@ type SortableListProps = {
159160
onMove: (oldTabIndex: number, newTabIndex: number) => void;
160161
onSelect: (tabIndex: number) => void;
161162
onClose: (tabIndex: number) => void;
163+
onCloseAllOthers: (tabIndex: number) => void;
162164
};
163165

164166
type WorkspaceTabsProps = {
@@ -168,6 +170,7 @@ type WorkspaceTabsProps = {
168170
onSelectNextTab: () => void;
169171
onSelectPrevTab: () => void;
170172
onCloseTab: (tabIndex: number) => void;
173+
onCloseAllOtherTabs: (tabIndex: number) => void;
171174
onMoveTab: (oldTabIndex: number, newTabIndex: number) => void;
172175
tabs: TabItem[];
173176
selectedTabIndex: number;
@@ -210,6 +213,7 @@ const SortableList = ({
210213
onSelect,
211214
selectedTabIndex,
212215
onClose,
216+
onCloseAllOthers,
213217
}: SortableListProps) => {
214218
const items = tabs.map((tab) => tab.id);
215219
const [activeId, setActiveId] = useState<UniqueIdentifier | null>(null);
@@ -267,6 +271,7 @@ const SortableList = ({
267271
activeId={activeId}
268272
onSelect={onSelect}
269273
onClose={onClose}
274+
onCloseAllOthers={onCloseAllOthers}
270275
selectedTabIndex={selectedTabIndex}
271276
/>
272277
))}
@@ -283,6 +288,7 @@ const SortableItem = ({
283288
activeId,
284289
onSelect,
285290
onClose,
291+
onCloseAllOthers,
286292
}: SortableItemProps) => {
287293
const onTabSelected = useCallback(() => {
288294
onSelect(index);
@@ -292,6 +298,10 @@ const SortableItem = ({
292298
onClose(index);
293299
}, [onClose, index]);
294300

301+
const onAllOthersTabsClosed = useCallback(() => {
302+
onCloseAllOthers(index);
303+
}, [onCloseAllOthers, index]);
304+
295305
const isSelected = useMemo(
296306
() => selectedTabIndex === index,
297307
[selectedTabIndex, index]
@@ -305,13 +315,15 @@ const SortableItem = ({
305315
tabContentId: tabId,
306316
onSelect: onTabSelected,
307317
onClose: onTabClosed,
318+
onCloseAllOthers: onAllOthersTabsClosed,
308319
});
309320
};
310321

311322
function WorkspaceTabs({
312323
['aria-label']: ariaLabel,
313324
onCreateNewTab,
314325
onCloseTab,
326+
onCloseAllOtherTabs,
315327
onMoveTab,
316328
onSelectTab,
317329
onSelectNextTab,
@@ -409,6 +421,7 @@ function WorkspaceTabs({
409421
onMove={onMoveTab}
410422
onSelect={onSelectTab}
411423
onClose={onCloseTab}
424+
onCloseAllOthers={onCloseAllOtherTabs}
412425
selectedTabIndex={selectedTabIndex}
413426
/>
414427
</div>

packages/compass-workspaces/src/components/workspaces.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
} from '../stores/workspaces';
1717
import {
1818
closeTab,
19+
closeAllOtherTabs,
1920
getActiveTab,
2021
moveTab,
2122
openFallbackWorkspace,
@@ -76,6 +77,7 @@ type CompassWorkspacesProps = {
7677
onMoveTab(from: number, to: number): void;
7778
onCreateTab(defaultTab?: OpenWorkspaceOptions | null): void;
7879
onCloseTab(at: number): void;
80+
onCloseAllOtherTabs(at: number): void;
7981
onNamespaceNotFound(
8082
tab: Extract<WorkspaceTab, { namespace: string }>,
8183
fallbackNamespace: string | null
@@ -94,6 +96,7 @@ const CompassWorkspaces: React.FunctionComponent<CompassWorkspacesProps> = ({
9496
onMoveTab,
9597
onCreateTab,
9698
onCloseTab,
99+
onCloseAllOtherTabs,
97100
onNamespaceNotFound,
98101
}) => {
99102
const { log, mongoLogId } = useLogger('COMPASS-WORKSPACES');
@@ -203,6 +206,7 @@ const CompassWorkspaces: React.FunctionComponent<CompassWorkspacesProps> = ({
203206
onMoveTab={onMoveTab}
204207
onCreateNewTab={onCreateNewTab}
205208
onCloseTab={onCloseTab}
209+
onCloseAllOtherTabs={onCloseAllOtherTabs}
206210
tabs={workspaceTabs}
207211
selectedTabIndex={activeTabIndex}
208212
></WorkspaceTabs>
@@ -235,6 +239,7 @@ export default connect(
235239
onMoveTab: moveTab,
236240
onCreateTab: openTabFromCurrent,
237241
onCloseTab: closeTab,
242+
onCloseAllOtherTabs: closeAllOtherTabs,
238243
onNamespaceNotFound: openFallbackWorkspace,
239244
}
240245
)(CompassWorkspaces);

packages/compass-workspaces/src/stores/workspaces.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export enum WorkspacesActions {
5656
MoveTab = 'compass-workspaces/MoveTab',
5757
OpenTabFromCurrentActive = 'compass-workspaces/OpenTabFromCurrentActive',
5858
CloseTab = 'compass-workspaces/CloseTab',
59+
CloseAllOtherTabs = 'compass-workspaces/CloseAllOtherTabs',
5960
CollectionRenamed = 'compass-workspaces/CollectionRenamed',
6061
CollectionRemoved = 'compass-workspaces/CollectionRemoved',
6162
DatabaseRemoved = 'compass-workspaces/DatabaseRemoved',
@@ -465,6 +466,20 @@ const reducer: Reducer<WorkspacesState, Action> = (
465466
});
466467
}
467468

469+
if (
470+
isAction<CloseAllOtherTabsAction>(
471+
action,
472+
WorkspacesActions.CloseAllOtherTabs
473+
)
474+
) {
475+
return _bulkTabsClose({
476+
state,
477+
isToBeClosed: (_tab, index) => {
478+
return index !== action.atIndex;
479+
},
480+
});
481+
}
482+
468483
if (
469484
isAction<CollectionRemovedAction>(
470485
action,
@@ -868,6 +883,27 @@ export const closeTab = (
868883
};
869884
};
870885

886+
type CloseAllOtherTabsAction = {
887+
type: WorkspacesActions.CloseAllOtherTabs;
888+
atIndex: number;
889+
};
890+
891+
export const closeAllOtherTabs = (
892+
atIndex: number
893+
): WorkspacesThunkAction<Promise<void>, CloseAllOtherTabsAction> => {
894+
return async (dispatch, getState) => {
895+
const { tabs } = getState();
896+
const otherTabs = tabs.filter((_, index) => index !== atIndex);
897+
for (const tab of otherTabs) {
898+
if (!canCloseTab(tab) && !(await confirmClosingTabs())) {
899+
return; // Abort the action
900+
}
901+
}
902+
dispatch({ type: WorkspacesActions.CloseAllOtherTabs, atIndex });
903+
cleanupLocalAppRegistryForTab(tabs[atIndex].id);
904+
};
905+
};
906+
871907
type CollectionRenamedAction = {
872908
type: WorkspacesActions.CollectionRenamed;
873909
from: string;

0 commit comments

Comments
 (0)