Skip to content

Commit d65413d

Browse files
committed
Add setting to hide sidebar worktrees and collapse them by default
Settings → Worktrees gains a "Show worktrees in sidebar" toggle (on by default) that hides the per-repo worktrees dropdown and skips its queries entirely. The dropdown also starts collapsed: expansion is tracked as the exception in a new expandedWorktreeSections set, since collapsedSections defaults sections to expanded. Generated-By: PostHog Code Task-Id: 24032eac-82cc-4c5f-a7e9-30ed9278a6e1
1 parent b7365ea commit d65413d

5 files changed

Lines changed: 66 additions & 6 deletions

File tree

packages/ui/src/features/settings/sections/worktrees/WorktreesSettings.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { useDeleteTask } from "../../../tasks/useTaskCrudMutations";
1616
import { useTasks } from "../../../tasks/useTasks";
1717
import { WORKSPACE_QUERY_KEY } from "../../../workspace/identifiers";
1818
import { SettingRow } from "../../SettingRow";
19+
import { useSettingsStore } from "../../settingsStore";
1920
import { WorktreeGroupSection } from "./WorktreeGroupSection";
2021

2122
const log = logger.scope("worktrees-settings");
@@ -25,6 +26,12 @@ export function WorktreesSettings() {
2526
const trpc = useHostTRPC();
2627
const hostClient = useHostTRPCClient();
2728
const { settings, updateSettings } = useSuspensionSettings();
29+
const showSidebarWorktrees = useSettingsStore(
30+
(state) => state.showSidebarWorktrees,
31+
);
32+
const setShowSidebarWorktrees = useSettingsStore(
33+
(state) => state.setShowSidebarWorktrees,
34+
);
2835
const { mutateAsync: deleteTask } = useDeleteTask();
2936
const [deletingWorktrees, setDeletingWorktrees] = useState<Set<string>>(
3037
new Set(),
@@ -133,6 +140,16 @@ export function WorktreesSettings() {
133140
return (
134141
<Flex direction="column" gap="5">
135142
<Flex direction="column">
143+
<SettingRow
144+
label="Show worktrees in sidebar"
145+
description="List worktrees that have no task under each repo in the sidebar, so you can start a task in one with a click"
146+
>
147+
<Switch
148+
checked={showSidebarWorktrees}
149+
onCheckedChange={setShowSidebarWorktrees}
150+
size="1"
151+
/>
152+
</SettingRow>
136153
<SettingRow
137154
label="Automatically suspend stale worktrees"
138155
description="Suspend stale worktrees to save disk space. Suspended worktrees can be restored at any time. Only disable if you prefer to manage worktrees manually."

packages/ui/src/features/settings/settingsStore.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,12 @@ interface SettingsStore {
230230
conversationCollapseMode: CollapseMode;
231231
setConversationCollapseMode: (mode: CollapseMode) => void;
232232

233+
// Sidebar
234+
// Shows a per-repo "Worktrees" dropdown of task-less worktrees a click can
235+
// start a task in.
236+
showSidebarWorktrees: boolean;
237+
setShowSidebarWorktrees: (enabled: boolean) => void;
238+
233239
// Experimental / misc
234240
hedgehogMode: boolean;
235241
slotMachineMode: boolean;
@@ -447,6 +453,11 @@ export const useSettingsStore = create<SettingsStore>()(
447453
setConversationCollapseMode: (mode) =>
448454
set({ conversationCollapseMode: mode }),
449455

456+
// Sidebar
457+
showSidebarWorktrees: true,
458+
setShowSidebarWorktrees: (enabled) =>
459+
set({ showSidebarWorktrees: enabled }),
460+
450461
// Experimental / misc
451462
hedgehogMode: false,
452463
slotMachineMode: false,
@@ -564,6 +575,9 @@ export const useSettingsStore = create<SettingsStore>()(
564575
// Conversation thread (new-thread)
565576
conversationCollapseMode: state.conversationCollapseMode,
566577

578+
// Sidebar
579+
showSidebarWorktrees: state.showSidebarWorktrees,
580+
567581
// Experimental / misc
568582
hedgehogMode: state.hedgehogMode,
569583
slotMachineMode: state.slotMachineMode,

packages/ui/src/features/sidebar/components/GroupWorktreesSection.tsx

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,20 @@ interface GroupWorktreesSectionProps {
1313
/**
1414
* Nested "Worktrees" dropdown at the bottom of a repo group listing the repo's
1515
* task-less worktrees. Clicking one starts a task in that worktree and opens
16-
* its chat + shell. Renders nothing when the repo has no adoptable worktrees.
16+
* its chat + shell. Collapsed by default; renders nothing when the repo has no
17+
* adoptable worktrees.
1718
*/
1819
export function GroupWorktreesSection({
1920
groupId,
2021
mainRepoPath,
2122
}: GroupWorktreesSectionProps) {
2223
const worktrees = useAdoptableWorktrees(mainRepoPath);
23-
const collapsedSections = useSidebarStore((state) => state.collapsedSections);
24-
const toggleSection = useSidebarStore((state) => state.toggleSection);
24+
const expandedWorktreeSections = useSidebarStore(
25+
(state) => state.expandedWorktreeSections,
26+
);
27+
const toggleWorktreeSection = useSidebarStore(
28+
(state) => state.toggleWorktreeSection,
29+
);
2530
const { startTask, startingBranches } =
2631
useStartTaskFromWorktree(mainRepoPath);
2732

@@ -34,8 +39,8 @@ export function GroupWorktreesSection({
3439
label={`Worktrees (${worktrees.length})`}
3540
icon={<TreeStructure size={14} className="text-gray-10" />}
3641
depth={1}
37-
isExpanded={!collapsedSections.has(sectionId)}
38-
onToggle={() => toggleSection(sectionId)}
42+
isExpanded={expandedWorktreeSections.has(sectionId)}
43+
onToggle={() => toggleWorktreeSection(sectionId)}
3944
tooltipContent="Worktrees without a task — click one to start a task there"
4045
>
4146
{worktrees.map((worktree) => {

packages/ui/src/features/sidebar/components/TaskListView.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { MenuLabel } from "@posthog/quill";
1515
import { getFileName } from "@posthog/shared";
1616
import { builderHog } from "@posthog/ui/assets/hedgehogs";
1717
import { useFolders } from "@posthog/ui/features/folders/useFolders";
18+
import { useSettingsStore } from "@posthog/ui/features/settings/settingsStore";
1819
import { useArchivingTasksStore } from "@posthog/ui/features/sidebar/archivingTasksStore";
1920
import { DraggableFolder } from "@posthog/ui/features/sidebar/components/DraggableFolder";
2021
import { GroupWorktreesSection } from "@posthog/ui/features/sidebar/components/GroupWorktreesSection";
@@ -189,6 +190,9 @@ export function TaskListView({
189190
(state) => state.resetHistoryVisibleCount,
190191
);
191192
const { folders } = useFolders();
193+
const showSidebarWorktrees = useSettingsStore(
194+
(state) => state.showSidebarWorktrees,
195+
);
192196
const view = useAppView();
193197
const isOnTaskInput =
194198
view.type === "task-input" || view.type === "task-pending";
@@ -370,7 +374,7 @@ export function TaskListView({
370374
/>
371375
))
372376
)}
373-
{folder && (
377+
{folder && showSidebarWorktrees && (
374378
<GroupWorktreesSection
375379
groupId={group.id}
376380
mainRepoPath={folder.mainRepoPath ?? folder.path}

packages/ui/src/features/sidebar/sidebarStore.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ interface SidebarStoreState {
1010
width: number;
1111
isResizing: boolean;
1212
collapsedSections: Set<string>;
13+
// Per-repo "Worktrees" subsections start collapsed, so unlike
14+
// collapsedSections this tracks the expanded exceptions.
15+
expandedWorktreeSections: Set<string>;
1316
folderOrder: string[];
1417
historyVisibleCount: number;
1518
organizeMode: "by-project" | "chronological";
@@ -30,6 +33,7 @@ interface SidebarStoreActions {
3033
setWidth: (width: number) => void;
3134
setIsResizing: (isResizing: boolean) => void;
3235
toggleSection: (sectionId: string) => void;
36+
toggleWorktreeSection: (sectionId: string) => void;
3337
reorderFolders: (fromIndex: number, toIndex: number) => void;
3438
setFolderOrder: (order: string[]) => void;
3539
syncFolderOrder: (folderIds: string[]) => void;
@@ -53,6 +57,7 @@ export const useSidebarStore = create<SidebarStore>()(
5357
width: 256,
5458
isResizing: false,
5559
collapsedSections: new Set<string>(),
60+
expandedWorktreeSections: new Set<string>(),
5661
folderOrder: [],
5762
historyVisibleCount: 25,
5863
organizeMode: "by-project",
@@ -78,6 +83,16 @@ export const useSidebarStore = create<SidebarStore>()(
7883
}
7984
return { collapsedSections: newCollapsedSections };
8085
}),
86+
toggleWorktreeSection: (sectionId) =>
87+
set((state) => {
88+
const next = new Set(state.expandedWorktreeSections);
89+
if (next.has(sectionId)) {
90+
next.delete(sectionId);
91+
} else {
92+
next.add(sectionId);
93+
}
94+
return { expandedWorktreeSections: next };
95+
}),
8196
reorderFolders: (fromIndex, toIndex) =>
8297
set((state) => {
8398
const newOrder = [...state.folderOrder];
@@ -126,6 +141,7 @@ export const useSidebarStore = create<SidebarStore>()(
126141
hasUserSetOpen: state.hasUserSetOpen,
127142
width: state.width,
128143
collapsedSections: Array.from(state.collapsedSections),
144+
expandedWorktreeSections: Array.from(state.expandedWorktreeSections),
129145
folderOrder: state.folderOrder,
130146
historyVisibleCount: state.historyVisibleCount,
131147
organizeMode: state.organizeMode,
@@ -141,6 +157,7 @@ export const useSidebarStore = create<SidebarStore>()(
141157
hasUserSetOpen?: boolean;
142158
width?: number;
143159
collapsedSections?: string[];
160+
expandedWorktreeSections?: string[];
144161
folderOrder?: string[];
145162
historyVisibleCount?: number;
146163
organizeMode?: SidebarStoreState["organizeMode"];
@@ -160,6 +177,9 @@ export const useSidebarStore = create<SidebarStore>()(
160177
persistedState.width ?? current.width,
161178
),
162179
collapsedSections: new Set(persistedState.collapsedSections ?? []),
180+
expandedWorktreeSections: new Set(
181+
persistedState.expandedWorktreeSections ?? [],
182+
),
163183
folderOrder: persistedState.folderOrder ?? [],
164184
historyVisibleCount:
165185
persistedState.historyVisibleCount ?? current.historyVisibleCount,

0 commit comments

Comments
 (0)