Skip to content

Commit 4b41f4a

Browse files
committed
Add the ability to collapse all folders from the context menu in the file tree panel
1 parent 98b046e commit 4b41f4a

File tree

6 files changed

+37
-3
lines changed

6 files changed

+37
-3
lines changed

apps/array/src/main/preload.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,8 +370,9 @@ contextBridge.exposeInMainWorld("electronAPI", {
370370
ipcRenderer.invoke("show-split-context-menu"),
371371
showFileContextMenu: (
372372
filePath: string,
373+
options?: { showCollapseAll?: boolean },
373374
): Promise<ExternalAppContextMenuResult> =>
374-
ipcRenderer.invoke("show-file-context-menu", filePath),
375+
ipcRenderer.invoke("show-file-context-menu", filePath, options),
375376
folders: {
376377
getFolders: (): Promise<RegisteredFolder[]> =>
377378
ipcRenderer.invoke("get-folders"),

apps/array/src/main/services/contextMenu.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,7 @@ export const showFileContextMenuService = createIpcService({
321321
handler: async (
322322
_event,
323323
filePath: string,
324+
options?: { showCollapseAll?: boolean },
324325
): Promise<ExternalAppContextMenuResult> => {
325326
return new Promise((resolve) => {
326327
const setupMenu = async () => {
@@ -329,7 +330,21 @@ export const showFileContextMenuService = createIpcService({
329330
resolve,
330331
);
331332

332-
showContextMenu(externalAppsItems, { action: null }).then(resolve);
333+
const template: MenuItemConstructorOptions[] = [];
334+
335+
if (options?.showCollapseAll) {
336+
template.push(
337+
{
338+
label: "Collapse All",
339+
click: () => resolve({ action: { type: "collapse-all" } }),
340+
},
341+
{ type: "separator" },
342+
);
343+
}
344+
345+
template.push(...externalAppsItems);
346+
347+
showContextMenu(template, { action: null }).then(resolve);
333348
};
334349

335350
setupMenu();

apps/array/src/main/services/contextMenu.types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
export type ExternalAppAction =
33
| { type: "open-in-app"; appId: string }
44
| { type: "copy-path" }
5+
| { type: "collapse-all" }
56
| null;
67

78
export interface ExternalAppContextMenuResult {

apps/array/src/renderer/features/right-sidebar/stores/fileTreeStore.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface FileTreeStoreState {
77

88
interface FileTreeStoreActions {
99
togglePath: (taskId: string, path: string) => void;
10+
collapseAll: (taskId: string) => void;
1011
}
1112

1213
type FileTreeStore = FileTreeStoreState & FileTreeStoreActions;
@@ -29,4 +30,11 @@ export const useFileTreeStore = create<FileTreeStore>()((set) => ({
2930
},
3031
};
3132
}),
33+
collapseAll: (taskId) =>
34+
set((state) => ({
35+
expandedPaths: {
36+
...state.expandedPaths,
37+
[taskId]: new Set<string>(),
38+
},
39+
})),
3240
}));

apps/array/src/renderer/features/task-detail/components/FileTreePanel.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ function LazyTreeItem({
4848
(state) => state.expandedPaths[taskId]?.has(entry.path) ?? false,
4949
);
5050
const togglePath = useFileTreeStore((state) => state.togglePath);
51+
const collapseAll = useFileTreeStore((state) => state.collapseAll);
5152
const openFile = usePanelLayoutStore((state) => state.openFile);
5253

5354
const { data: children } = useQuery({
@@ -70,10 +71,17 @@ function LazyTreeItem({
7071

7172
const handleContextMenu = async (e: React.MouseEvent) => {
7273
e.preventDefault();
73-
const result = await window.electronAPI.showFileContextMenu(entry.path);
74+
const result = await window.electronAPI.showFileContextMenu(entry.path, {
75+
showCollapseAll: true,
76+
});
7477

7578
if (!result.action) return;
7679

80+
if (result.action.type === "collapse-all") {
81+
collapseAll(taskId);
82+
return;
83+
}
84+
7785
await handleExternalAppAction(result.action, entry.path, entry.name);
7886
};
7987

apps/array/src/renderer/types/electron.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ declare global {
262262
showSplitContextMenu: () => Promise<SplitContextMenuResult>;
263263
showFileContextMenu: (
264264
filePath: string,
265+
options?: { showCollapseAll?: boolean },
265266
) => Promise<ExternalAppContextMenuResult>;
266267
folders: {
267268
getFolders: () => Promise<RegisteredFolder[]>;

0 commit comments

Comments
 (0)