mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 00:27:39 +00:00
Carry the project host on GitHub item dialog origins
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -134,13 +134,19 @@ vi.mock('./github-api-repository', async (importOriginal) => {
|
||||
// Mirror production: dotcom origin slugs come back pinned to github.com.
|
||||
return slug ? { host: 'github.com', ...slug } : slug
|
||||
},
|
||||
getIssueGitHubApiRepository: (repoPath: string, connectionId?: string | null) =>
|
||||
getIssueOwnerRepoMock(repoPath, connectionId),
|
||||
getIssueGitHubApiRepository: async (repoPath: string, connectionId?: string | null) => {
|
||||
const slug = await getIssueOwnerRepoMock(repoPath, connectionId)
|
||||
// Mirror production: issue slugs come back host-qualified to github.com.
|
||||
return slug ? { host: 'github.com', ...slug } : slug
|
||||
},
|
||||
resolveIssueGitHubApiRepositorySource: async (
|
||||
repoPath: string,
|
||||
_preference: unknown,
|
||||
connectionId?: string | null
|
||||
) => ({ source: await getIssueOwnerRepoMock(repoPath, connectionId), fellBack: false })
|
||||
) => {
|
||||
const slug = await getIssueOwnerRepoMock(repoPath, connectionId)
|
||||
return { source: slug ? { host: 'github.com', ...slug } : slug, fellBack: false }
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -65,6 +65,11 @@ export async function getIssue(
|
||||
connectionId,
|
||||
localGitOptions
|
||||
)
|
||||
// Why: a connection-backed request has no local cwd, so the non-GitHub
|
||||
// fallback below would let gh target its default repository. Refuse instead.
|
||||
if (connectionId && !ownerRepo) {
|
||||
return null
|
||||
}
|
||||
await acquire()
|
||||
try {
|
||||
if (ownerRepo) {
|
||||
@@ -126,6 +131,17 @@ export async function listIssues(
|
||||
connectionId,
|
||||
localGitOptions
|
||||
)
|
||||
// Why: a connection-backed request has no local cwd, so the non-GitHub
|
||||
// fallback below would let gh list its default repository. Refuse instead.
|
||||
if (connectionId && !ownerRepo) {
|
||||
return {
|
||||
items: [],
|
||||
error: {
|
||||
type: 'not_found',
|
||||
message: 'Could not resolve GitHub owner/repo for this repository'
|
||||
}
|
||||
}
|
||||
}
|
||||
await acquire()
|
||||
try {
|
||||
if (ownerRepo) {
|
||||
|
||||
@@ -297,6 +297,8 @@ function normalizeItemDialogTab(
|
||||
export type GitHubItemDialogProjectOrigin = {
|
||||
owner: string
|
||||
repo: string
|
||||
/** GitHub host (e.g. GHES); absent means github.com. */
|
||||
host?: string
|
||||
number: number
|
||||
type: 'issue' | 'pr'
|
||||
projectId: string
|
||||
|
||||
@@ -399,6 +399,7 @@ export default function ProjectViewWrapper({ selectedRepoIds }: Props): React.JS
|
||||
const [repoNotInOrca, setRepoNotInOrca] = useState<{
|
||||
owner: string
|
||||
repo: string
|
||||
host?: string
|
||||
url: string | null
|
||||
} | null>(null)
|
||||
const liveRepoIds = useMemo(() => new Set(repos.map((repo) => repo.id)), [repos])
|
||||
@@ -597,6 +598,7 @@ export default function ProjectViewWrapper({ selectedRepoIds }: Props): React.JS
|
||||
const resolution = resolveSelectedProjectRowRepo({
|
||||
row,
|
||||
lookupSlug,
|
||||
host: table.project.host,
|
||||
slugIndexReady,
|
||||
selectedRepoIds
|
||||
})
|
||||
@@ -614,6 +616,7 @@ export default function ProjectViewWrapper({ selectedRepoIds }: Props): React.JS
|
||||
setRepoNotInOrca({
|
||||
owner: origin.owner,
|
||||
repo: origin.repo,
|
||||
host: origin.host,
|
||||
url: row.content.url ?? null
|
||||
})
|
||||
return
|
||||
|
||||
@@ -6,27 +6,30 @@ type SlugProjectDialogState = {
|
||||
origin: {
|
||||
owner: string
|
||||
repo: string
|
||||
host?: string
|
||||
}
|
||||
}
|
||||
|
||||
type RepoNotInOrcaDialogState = {
|
||||
owner: string
|
||||
repo: string
|
||||
host?: string
|
||||
}
|
||||
|
||||
type RepoMatch = {
|
||||
id: string
|
||||
}
|
||||
|
||||
type LookupSlug = (slug: string) => readonly RepoMatch[]
|
||||
type LookupSlug = (slug: string, host?: string) => readonly RepoMatch[]
|
||||
|
||||
function shouldCloseFallbackDialog(args: {
|
||||
lookupSlug: LookupSlug
|
||||
selectedRepoIds: ReadonlySet<string>
|
||||
owner: string
|
||||
repo: string
|
||||
host?: string
|
||||
}): boolean {
|
||||
const matches = args.lookupSlug(`${args.owner}/${args.repo}`)
|
||||
const matches = args.lookupSlug(`${args.owner}/${args.repo}`, args.host)
|
||||
const selectedMatchCount = matches.filter((match) => args.selectedRepoIds.has(match.id)).length
|
||||
const unselectedMatchCount = matches.length - selectedMatchCount
|
||||
return selectedMatchCount > 0 || unselectedMatchCount > 0
|
||||
@@ -67,7 +70,8 @@ export function resolveMissingRepoProjectDialogState<
|
||||
lookupSlug,
|
||||
selectedRepoIds,
|
||||
owner: slugDialog.origin.owner,
|
||||
repo: slugDialog.origin.repo
|
||||
repo: slugDialog.origin.repo,
|
||||
host: slugDialog.origin.host
|
||||
})
|
||||
? null
|
||||
: slugDialog,
|
||||
@@ -77,7 +81,8 @@ export function resolveMissingRepoProjectDialogState<
|
||||
lookupSlug,
|
||||
selectedRepoIds,
|
||||
owner: repoNotInOrca.owner,
|
||||
repo: repoNotInOrca.repo
|
||||
repo: repoNotInOrca.repo,
|
||||
host: repoNotInOrca.host
|
||||
})
|
||||
? null
|
||||
: repoNotInOrca
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
getFreshMetadata,
|
||||
loadMetadata
|
||||
} from './metadata-request-cache'
|
||||
import { githubRepoIdentityKey } from '../../../shared/github-repository-identity-key'
|
||||
|
||||
type MetadataState<T> = {
|
||||
data: T
|
||||
@@ -36,7 +37,8 @@ export function clearGitHubSlugMetadataCache(): void {
|
||||
export function useRepoLabelsBySlug(
|
||||
owner: string | null,
|
||||
repo: string | null,
|
||||
settings?: Pick<GlobalSettings, 'activeRuntimeEnvironmentId'> | null
|
||||
settings?: Pick<GlobalSettings, 'activeRuntimeEnvironmentId'> | null,
|
||||
host?: string
|
||||
): MetadataState<string[]> {
|
||||
const [state, setState] = useState<MetadataState<string[]>>({
|
||||
data: [],
|
||||
@@ -55,10 +57,11 @@ export function useRepoLabelsBySlug(
|
||||
return
|
||||
}
|
||||
const target = getActiveRuntimeTarget({ activeRuntimeEnvironmentId })
|
||||
const repositoryKey = githubRepoIdentityKey({ owner, repo, host })
|
||||
const key =
|
||||
target.kind === 'environment'
|
||||
? `runtime:${target.environmentId}:${owner}/${repo}`
|
||||
: `${owner}/${repo}`
|
||||
? `runtime:${target.environmentId}:${repositoryKey}`
|
||||
: repositoryKey
|
||||
|
||||
const cached = getFreshMetadata(slugLabelStore, key)
|
||||
if (cached) {
|
||||
@@ -85,10 +88,10 @@ export function useRepoLabelsBySlug(
|
||||
? callRuntimeRpc<ListLabelsBySlugResult>(
|
||||
target,
|
||||
'github.project.listLabelsBySlug',
|
||||
{ owner, repo },
|
||||
{ owner, repo, ...(host ? { host } : {}) },
|
||||
{ timeoutMs: 30_000 }
|
||||
)
|
||||
: window.api.gh.listLabelsBySlug({ owner, repo })
|
||||
: window.api.gh.listLabelsBySlug({ owner, repo, ...(host ? { host } : {}) })
|
||||
).then((res) => {
|
||||
if (!res.ok) {
|
||||
throw new Error(res.error.message)
|
||||
@@ -113,7 +116,7 @@ export function useRepoLabelsBySlug(
|
||||
error: err instanceof Error ? err.message : 'Failed to load labels'
|
||||
}))
|
||||
})
|
||||
}, [owner, repo, activeRuntimeEnvironmentId])
|
||||
}, [owner, repo, host, activeRuntimeEnvironmentId])
|
||||
|
||||
return state
|
||||
}
|
||||
@@ -122,7 +125,8 @@ export function useRepoAssigneesBySlug(
|
||||
owner: string | null,
|
||||
repo: string | null,
|
||||
seedLogins?: string[],
|
||||
settings?: Pick<GlobalSettings, 'activeRuntimeEnvironmentId'> | null
|
||||
settings?: Pick<GlobalSettings, 'activeRuntimeEnvironmentId'> | null,
|
||||
host?: string
|
||||
): MetadataState<GitHubAssignableUser[]> {
|
||||
const [state, setState] = useState<MetadataState<GitHubAssignableUser[]>>({
|
||||
data: [],
|
||||
@@ -143,10 +147,11 @@ export function useRepoAssigneesBySlug(
|
||||
return
|
||||
}
|
||||
const target = getActiveRuntimeTarget({ activeRuntimeEnvironmentId })
|
||||
const repositoryKey = githubRepoIdentityKey({ owner, repo, host })
|
||||
const key =
|
||||
target.kind === 'environment'
|
||||
? `runtime:${target.environmentId}:${owner}/${repo}#${seedKey}`
|
||||
: `${owner}/${repo}#${seedKey}`
|
||||
? `runtime:${target.environmentId}:${repositoryKey}#${seedKey}`
|
||||
: `${repositoryKey}#${seedKey}`
|
||||
|
||||
const cached = getFreshMetadata(slugAssigneeStore, key)
|
||||
if (cached) {
|
||||
@@ -173,6 +178,7 @@ export function useRepoAssigneesBySlug(
|
||||
const args = {
|
||||
owner,
|
||||
repo,
|
||||
...(host ? { host } : {}),
|
||||
...(seedKey ? { seedLogins: seedKey.split(',') } : {})
|
||||
}
|
||||
loadMetadata(slugAssigneeStore, key, () =>
|
||||
@@ -208,7 +214,7 @@ export function useRepoAssigneesBySlug(
|
||||
error: err instanceof Error ? err.message : 'Failed to load assignees'
|
||||
}))
|
||||
})
|
||||
}, [owner, repo, seedKey, activeRuntimeEnvironmentId])
|
||||
}, [owner, repo, host, seedKey, activeRuntimeEnvironmentId])
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
@@ -15,11 +15,17 @@ export function settingsForProjectRowOwner(
|
||||
state: RepoOwnerState,
|
||||
owner: string,
|
||||
repo: string,
|
||||
host?: string,
|
||||
fallbackSettings:
|
||||
| Pick<GlobalSettings, 'activeRuntimeEnvironmentId'>
|
||||
| null
|
||||
| undefined = state.settings
|
||||
): Pick<GlobalSettings, 'activeRuntimeEnvironmentId'> | null | undefined {
|
||||
const matchedRepo = lookupReposBySlugFromCache(state.repos, state.settings, `${owner}/${repo}`)[0]
|
||||
const matchedRepo = lookupReposBySlugFromCache(
|
||||
state.repos,
|
||||
state.settings,
|
||||
`${owner}/${repo}`,
|
||||
host
|
||||
)[0]
|
||||
return matchedRepo ? getSettingsForRepoRuntimeOwner(state, matchedRepo.id) : fallbackSettings
|
||||
}
|
||||
|
||||
@@ -2377,6 +2377,7 @@ export const createGitHubSlice: StateCreator<AppState, [], [], GitHubSlice> = (s
|
||||
get(),
|
||||
owner,
|
||||
repo,
|
||||
table.project.host,
|
||||
settingsForProjectViewCacheKey(get().settings, cacheKey)
|
||||
)
|
||||
)
|
||||
@@ -2506,6 +2507,7 @@ export const createGitHubSlice: StateCreator<AppState, [], [], GitHubSlice> = (s
|
||||
get(),
|
||||
owner,
|
||||
repo,
|
||||
table.project.host,
|
||||
settingsForProjectViewCacheKey(get().settings, cacheKey)
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user