fix(tasks): hide repos without remote identity (#9898)
This commit is contained in:
parent
108a2ad41b
commit
fa09d6fd8e
|
|
@ -179,7 +179,6 @@ import {
|
|||
readLinearBoardIssueDragData,
|
||||
writeLinearBoardIssueDragData
|
||||
} from '@/lib/linear-board-drag-payload'
|
||||
import { isGitRepoKind } from '../../../shared/repo-kind'
|
||||
import { getRepoExecutionHostId } from '../../../shared/execution-host'
|
||||
import { projectHostSetupProjectionFromRepos } from '../../../shared/project-host-setup-projection'
|
||||
import { TASK_SOURCE_CONTEXT_RUNTIME_CAPABILITY } from '../../../shared/protocol-version'
|
||||
|
|
@ -238,6 +237,7 @@ import { findTaskPageJiraIssue } from '@/components/task-page-jira-cache-selecto
|
|||
import { getRepoBackedTaskEmptyState } from '@/components/task-page-empty-state'
|
||||
import {
|
||||
getDefaultTaskRepoSelection,
|
||||
getTaskEligibleRepos,
|
||||
getTaskProjectPickerGroups,
|
||||
normalizeTaskRepoSelection
|
||||
} from '@/components/task-page-default-repo-selection'
|
||||
|
|
@ -3141,7 +3141,7 @@ export default function TaskPage(): React.JSX.Element {
|
|||
const linearConnected = linearStatusCurrent && linearStatus.connected
|
||||
const jiraConnected = jiraStatusCurrent && jiraStatus.connected
|
||||
const submitShortcutLabel = getScreenSubmitShortcutLabel()
|
||||
const eligibleRepos = useMemo(() => repos.filter((repo) => isGitRepoKind(repo)), [repos])
|
||||
const eligibleRepos = useMemo(() => getTaskEligibleRepos(repos), [repos])
|
||||
|
||||
// Why: initial selection precedence — explicit preselection > persisted defaultRepoSelection > all eligible; preselection wins so "open tasks for this repo" lands single-repo.
|
||||
const resolvedInitialSelection = useMemo<ReadonlySet<string>>(() => {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest'
|
|||
import type { Repo } from '../../../shared/types'
|
||||
import {
|
||||
getDefaultTaskRepoSelection,
|
||||
getTaskEligibleRepos,
|
||||
getTaskProjectPickerGroups,
|
||||
getTaskProjectPickerRepos,
|
||||
normalizeTaskRepoSelection
|
||||
|
|
@ -18,6 +19,51 @@ function repo(overrides: Partial<Repo> & Pick<Repo, 'id'>): Repo {
|
|||
}
|
||||
}
|
||||
|
||||
describe('getTaskEligibleRepos', () => {
|
||||
it('keeps only Git repos with a resolvable remote identity', () => {
|
||||
const eligible = getTaskEligibleRepos([
|
||||
repo({ id: 'github-upstream', upstream: { owner: 'stablyai', repo: 'orca' } }),
|
||||
repo({
|
||||
id: 'github-icon',
|
||||
repoIcon: {
|
||||
type: 'image',
|
||||
src: 'https://github.com/stablyai.png?size=64',
|
||||
source: 'github',
|
||||
label: 'stablyai/orca'
|
||||
}
|
||||
}),
|
||||
repo({
|
||||
id: 'gitlab-remote',
|
||||
gitRemoteIdentity: {
|
||||
canonicalKey: 'gitlab.example.com/team/orca',
|
||||
remoteName: 'origin',
|
||||
remoteUrl: 'git@gitlab.example.com:team/orca.git'
|
||||
}
|
||||
}),
|
||||
repo({ id: 'local-only' }),
|
||||
repo({
|
||||
id: 'incomplete-remote',
|
||||
gitRemoteIdentity: {
|
||||
canonicalKey: 'gitlab.example.com/team/incomplete',
|
||||
remoteName: '',
|
||||
remoteUrl: 'git@gitlab.example.com:team/incomplete.git'
|
||||
}
|
||||
}),
|
||||
repo({
|
||||
id: 'folder-with-remote',
|
||||
kind: 'folder',
|
||||
upstream: { owner: 'stablyai', repo: 'docs' }
|
||||
})
|
||||
])
|
||||
|
||||
expect(eligible.map((candidate) => candidate.id)).toEqual([
|
||||
'github-upstream',
|
||||
'github-icon',
|
||||
'gitlab-remote'
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
describe('getDefaultTaskRepoSelection', () => {
|
||||
it('selects one source per logical GitHub project', () => {
|
||||
const selection = getDefaultTaskRepoSelection([
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import { getRepoExecutionHostId, LOCAL_EXECUTION_HOST_ID } from '../../../shared/execution-host'
|
||||
import { getProjectIdentityKey } from '../../../shared/project-host-setup-projection'
|
||||
import {
|
||||
getProjectIdentityKey,
|
||||
hasProjectRemoteIdentity
|
||||
} from '../../../shared/project-host-setup-projection'
|
||||
import { isGitRepoKind } from '../../../shared/repo-kind'
|
||||
import type { Repo } from '../../../shared/types'
|
||||
|
||||
export type TaskProjectPickerGroup = {
|
||||
|
|
@ -8,6 +12,10 @@ export type TaskProjectPickerGroup = {
|
|||
sources: Repo[]
|
||||
}
|
||||
|
||||
export function getTaskEligibleRepos(repos: readonly Repo[]): Repo[] {
|
||||
return repos.filter((repo) => isGitRepoKind(repo) && hasProjectRemoteIdentity(repo))
|
||||
}
|
||||
|
||||
export function getDefaultTaskRepoSelection(repos: readonly Repo[]): Set<string> {
|
||||
const selectedByProject = new Map<string, Repo>()
|
||||
for (const repo of repos) {
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ export function isGitHubBackedRepo(
|
|||
return getProjectProviderIdentity(repo) !== null
|
||||
}
|
||||
|
||||
export function hasProjectRemoteIdentity(
|
||||
repo: Pick<Repo, 'upstream' | 'repoIcon' | 'gitRemoteIdentity'>
|
||||
): boolean {
|
||||
return getProjectProviderIdentity(repo) !== null || getProjectGitRemoteIdentity(repo) !== null
|
||||
}
|
||||
|
||||
export function getProjectIdentityKey(
|
||||
repo: Pick<Repo, 'id' | 'upstream' | 'repoIcon' | 'gitRemoteIdentity'>
|
||||
): string {
|
||||
|
|
|
|||
Loading…
Reference in New Issue