perf: reuse normalized task-page repository selection (#19454)

* perf: reuse normalized task-page repository selection

* test(task-page): cover ineligible persisted repo IDs in initial selection

---------

Co-authored-by: m4air <m4air@m4airs-MacBook-Air.local>
Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com>
This commit is contained in:
OrcaWin
2026-09-08 19:55:25 -07:00
committed by GitHub
co-authored by m4air Neil
parent eedaf2bdfc
commit 98df62d8ff
2 changed files with 89 additions and 5 deletions
@@ -0,0 +1,88 @@
import { describe, expect, it } from 'vitest'
import { renderToString } from 'react-dom/server'
import type { Repo } from '../../../shared/repo-types'
import type { TaskPageStoreBindingsModel } from './use-task-page-store-bindings'
import { useTaskPageRepoSelection } from './use-task-page-repo-selection'
function resolveSelection(repos: Repo[], persisted: string[], preferred?: string) {
let selected: readonly string[] = []
function Probe() {
const model = {
repos,
settings: { defaultRepoSelection: persisted },
pageData: { preselectedRepoId: preferred },
linearStatus: {},
jiraStatus: {},
preflightStatus: null
} as unknown as TaskPageStoreBindingsModel
useTaskPageRepoSelection(model)
selected = [
...(model as TaskPageStoreBindingsModel & { resolvedInitialSelection: ReadonlySet<string> })
.resolvedInitialSelection
]
return null
}
renderToString(<Probe />)
return selected
}
describe('task page initial repo selection', () => {
it('normalizes persisted selections without a repository scan for every stored ID', () => {
let reads = 0
const repos: Repo[] = Array.from({ length: 1000 }, (_, index) => ({
get id() {
reads++
return `repo-${index}`
},
path: `/repos/${index}`,
displayName: `Repo ${index}`,
badgeColor: '',
addedAt: index,
kind: 'git'
}))
const persisted = Array.from({ length: 1000 }, (_, index) => `repo-${index}`)
expect(resolveSelection(repos, persisted)).toEqual(persisted)
expect(reads).toBeLessThan(40_000)
})
it('retains preferred selection, missing-ID fallback, and explicit empty defaults', () => {
const repos: Repo[] = ['a', 'b'].map((id) => ({
id,
path: `/repos/${id}`,
displayName: id,
badgeColor: '',
addedAt: 0,
kind: 'git'
}))
expect(resolveSelection(repos, ['b'], 'a')).toEqual(['a'])
expect(resolveSelection(repos, ['missing'])).toEqual(['a', 'b'])
expect(resolveSelection(repos, [])).toEqual(['a', 'b'])
expect(resolveSelection(repos, ['missing', 'b', 'b'])).toEqual(['b'])
})
it('ignores persisted IDs for ineligible repos, including folder workspaces', () => {
const repos: Repo[] = [
{
id: 'tracked',
path: '/repos/tracked',
displayName: 'tracked',
badgeColor: '',
addedAt: 0,
kind: 'git'
},
{
id: 'folder',
path: '/repos/folder',
displayName: 'folder',
badgeColor: '',
addedAt: 1,
kind: 'folder'
}
]
// A folder workspace is never task-eligible, so a stored selection naming only one must fall
// through to the automatic default rather than rendering an empty picker.
expect(resolveSelection(repos, ['folder'])).toEqual(['tracked'])
expect(resolveSelection(repos, ['folder', 'tracked'])).toEqual(['tracked'])
})
})
@@ -51,11 +51,7 @@ export function useTaskPageRepoSelection(model: TaskPageStoreBindingsModel) {
}
const persisted = settings?.defaultRepoSelection
if (Array.isArray(persisted)) {
const filtered = persisted.filter((id) => eligibleRepos.some((r) => r.id === id))
if (filtered.length > 0) {
return normalizeTaskRepoSelection(eligibleRepos, new Set(filtered))
}
// Why: empty after filtering (all persisted repos removed) falls through to the automatic default so the page never renders an empty selection.
return normalizeTaskRepoSelection(eligibleRepos, new Set(persisted))
}
return getDefaultTaskRepoSelection(eligibleRepos)
}, [eligibleRepos, pageData.preselectedRepoId, settings?.defaultRepoSelection])