fix(sidebar): scope folder-backed geometry by owner

This commit is contained in:
Brennan Benson
2026-08-10 19:53:00 -07:00
parent 2237947314
commit 3663228541
2 changed files with 26 additions and 17 deletions
@@ -91,6 +91,7 @@ import {
PINNED_GROUP_KEY,
buildRows,
buildProjectGroupSidebarIndex,
findProjectGroupForRepo,
getAmbiguousFolderWorkspaceSidebarIds,
getProjectGroupHeaderKey,
getProjectGroupMutationSelector,
@@ -1477,13 +1478,13 @@ const VirtualizedWorktreeViewport = React.memo(function VirtualizedWorktreeViewp
scrollAnchorRef
}: VirtualizedWorktreeViewportProps) {
const activeWorkspaceExecutionHostId = useAppStore((s) => s.activeWorkspaceExecutionHostId)
const projectGroupSidebarIndex = useMemo(
() => buildProjectGroupSidebarIndex(projectGroups),
[projectGroups]
)
const ambiguousFolderWorkspaceIds = useMemo(
() =>
getAmbiguousFolderWorkspaceSidebarIds(
buildProjectGroupSidebarIndex(projectGroups),
folderWorkspaces
),
[folderWorkspaces, projectGroups]
() => getAmbiguousFolderWorkspaceSidebarIds(projectGroupSidebarIndex, folderWorkspaces),
[folderWorkspaces, projectGroupSidebarIndex]
)
const scrollRef = useRef<HTMLDivElement>(null)
const suppressMeasurementAdjustmentUntilRef = useRef(0)
@@ -1599,15 +1600,6 @@ const VirtualizedWorktreeViewport = React.memo(function VirtualizedWorktreeViewp
const settings = useAppStore((s) => s.settings)
const newCardStyle = settings?.experimentalNewWorktreeCardStyle === true
const reorderRepos = useAppStore((s) => s.reorderRepos)
const folderBackedProjectGroupIds = useMemo(
() =>
new Set(
projectGroups
.filter((group) => group.createdFrom === 'folder-scan')
.map((group) => group.id)
),
[projectGroups]
)
const projectGroupByIdForHeaderDrag = useMemo(
() => new Map(renderedProjectGroupsForHeaderDrag.map((group) => [group.id, group])),
[renderedProjectGroupsForHeaderDrag]
@@ -4930,10 +4922,10 @@ const VirtualizedWorktreeViewport = React.memo(function VirtualizedWorktreeViewp
const lineageToggleGroupKey = itemRow.lineageGroupKey
const experimentalNewWorktreeCardStyle =
settings?.experimentalNewWorktreeCardStyle === true
const projectGroupId = itemRow.repo?.projectGroupId
const isFolderBackedRepoChild =
groupBy === 'repo' &&
Boolean(projectGroupId && folderBackedProjectGroupIds.has(projectGroupId))
findProjectGroupForRepo(projectGroupSidebarIndex, itemRow.repo, defaultHostId)
?.createdFrom === 'folder-scan'
// Why: experimental in-card lineage inherits the parent surface; legacy cards keep depth-based nested geometry.
const paddingDepth = nested ? Math.max(0, itemRow.depth - 1) : itemRow.depth
const getCardContentIndent = (lineageDepth: number): number =>
@@ -12,6 +12,7 @@ import type { FolderWorkspace, ProjectGroup, Repo, Worktree } from '../../../../
import {
buildRows,
buildProjectGroupSidebarIndex,
findProjectGroupForRepo,
findProjectGroupForSidebarOwner,
getAmbiguousFolderWorkspaceSidebarIds,
getProjectGroupMutationSelector,
@@ -165,6 +166,22 @@ describe('project-group sidebar identity', () => {
expect(getProjectGroupSidebarIdentity(local)).not.toBe(getProjectGroupSidebarIdentity(runtime))
})
it('keeps folder-backed card geometry scoped to the repo owner', () => {
const local = { ...sidebarIdentityGroup('same-id', 'local'), createdFrom: 'manual' as const }
const runtime = {
...sidebarIdentityGroup('same-id', 'runtime:env-1'),
createdFrom: 'folder-scan' as const
}
const index = buildProjectGroupSidebarIndex([local, runtime])
expect(findProjectGroupForRepo(index, ownerHeaderRepo('local-repo', 'local'), 'local')).toBe(
local
)
expect(
findProjectGroupForRepo(index, ownerHeaderRepo('runtime-repo', 'runtime:env-1'), 'local')
).toBe(runtime)
})
it('carries the exact owner from a rendered header into mutations', () => {
const runtime = sidebarIdentityGroup('same-id', 'runtime:env-1')