mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(gitlab): label hosted reviews per provider in the space-manager panel (#7655)
The workspace space-manager rendered every hosted review as "PR #N", so a GitLab merge request showed as "PR #5" instead of "MR !5". The cached review already carries its provider (HostedReviewInfo.provider) — the panel's local input type just narrowed it away. Thread provider through and format via the same localizedHostedReviewCopy / '!' vs '#' helpers the rest of the app uses. Extract the label formatting into hosted-review-label.ts (a pure module, away from the panel's heavy React/store imports) so it can be unit-tested directly, and add hosted-review-label.test.ts covering github / gitlab / azure-devops / gitea and the status suffix. linkedPR stays "PR #N" — it is the GitHub-specific workspace field, distinct from linkedGitLabMR. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Neil <4138956+nwparker@users.noreply.github.com> Co-authored-by: Neil <neil@stably.ai>
This commit is contained in:
co-authored by
Claude Opus 4.8
Neil
Neil
parent
6fd0682ac1
commit
831c394797
@@ -0,0 +1,39 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { formatHostedReviewLabel } from './hosted-review-label'
|
||||
|
||||
describe('formatHostedReviewLabel', () => {
|
||||
it('labels a GitLab review as "MR !N" — not "PR #N"', () => {
|
||||
expect(
|
||||
formatHostedReviewLabel({ provider: 'gitlab', number: 5, state: 'open', status: 'none' })
|
||||
).toBe('MR !5 Open')
|
||||
})
|
||||
|
||||
it.each([
|
||||
['github' as const, 'PR #7 Open'],
|
||||
['azure-devops' as const, 'PR #7 Open'],
|
||||
['gitea' as const, 'PR #7 Open'],
|
||||
['bitbucket' as const, 'PR #7 Open']
|
||||
])('uses the "PR #" form and correct copy for %s', (provider, expected) => {
|
||||
expect(formatHostedReviewLabel({ provider, number: 7, state: 'open', status: 'none' })).toBe(
|
||||
expected
|
||||
)
|
||||
})
|
||||
|
||||
it('keeps the GitHub label for older cached reviews without a provider', () => {
|
||||
expect(formatHostedReviewLabel({ number: 42, state: 'open', status: 'none' })).toBe(
|
||||
'PR #42 Open'
|
||||
)
|
||||
})
|
||||
|
||||
it('appends a non-"none" status suffix', () => {
|
||||
expect(
|
||||
formatHostedReviewLabel({ provider: 'gitlab', number: 5, state: 'open', status: 'draft' })
|
||||
).toBe('MR !5 Open, draft')
|
||||
})
|
||||
|
||||
it('omits the suffix when status is "none" or empty', () => {
|
||||
expect(
|
||||
formatHostedReviewLabel({ provider: 'github', number: 5, state: 'closed', status: '' })
|
||||
).toBe('PR #5 Closed')
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,23 @@
|
||||
import type { HostedReviewProvider } from '../../../../shared/hosted-review'
|
||||
import {
|
||||
localizedHostedReviewCopy,
|
||||
resolveSupportedHostedReviewCopyProvider
|
||||
} from '@/i18n/hosted-review-localized-copy'
|
||||
|
||||
function formatReviewState(state: string): string {
|
||||
return state.charAt(0).toUpperCase() + state.slice(1)
|
||||
}
|
||||
|
||||
export function formatHostedReviewLabel(review: {
|
||||
provider?: HostedReviewProvider
|
||||
number: number
|
||||
state: string
|
||||
status: string
|
||||
}): string {
|
||||
const { shortLabel } = localizedHostedReviewCopy(
|
||||
resolveSupportedHostedReviewCopyProvider(review.provider)
|
||||
)
|
||||
const symbol = review.provider === 'gitlab' ? '!' : '#'
|
||||
const statusSuffix = review.status && review.status !== 'none' ? `, ${review.status}` : ''
|
||||
return `${shortLabel} ${symbol}${review.number} ${formatReviewState(review.state)}${statusSuffix}`
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import { issueCacheKey as getIssueCacheKey } from '../../store/github/cache-iden
|
||||
import { countWorkspaceSpaceActiveAgents } from './workspace-space-presentation'
|
||||
import { getWorkspaceSpaceWorktreeIdentity } from './workspace-space-delete-selection'
|
||||
import { getWorkspaceSpaceBranchLabel } from './workspace-space-format'
|
||||
import { formatHostedReviewLabel } from './hosted-review-label'
|
||||
|
||||
export type WorkspaceDecisionDetails = {
|
||||
isActive: boolean
|
||||
@@ -78,10 +79,6 @@ export function pluralize(count: number, singular: string, plural = `${singular}
|
||||
return `${count} ${count === 1 ? singular : plural}`
|
||||
}
|
||||
|
||||
function formatReviewState(state: string): string {
|
||||
return state.charAt(0).toUpperCase() + state.slice(1)
|
||||
}
|
||||
|
||||
function countLiveTerminals(
|
||||
tabs: readonly TerminalTab[],
|
||||
ptyIdsByTabId: Record<string, string[]>
|
||||
@@ -156,9 +153,7 @@ export function getWorkspaceDecisionDetails(
|
||||
const linkedPR = workspaceRecord?.linkedPR ?? null
|
||||
const reviewLabel =
|
||||
hostedReview !== undefined && hostedReview !== null
|
||||
? `PR #${hostedReview.number} ${formatReviewState(hostedReview.state)}${
|
||||
hostedReview.status && hostedReview.status !== 'none' ? `, ${hostedReview.status}` : ''
|
||||
}`
|
||||
? formatHostedReviewLabel(hostedReview)
|
||||
: linkedPR
|
||||
? `PR #${linkedPR}`
|
||||
: null
|
||||
|
||||
@@ -564,7 +564,7 @@ describe('workspace space presentation helpers', () => {
|
||||
)
|
||||
|
||||
expect(explicit.reviewLabel).toBe('PR #12 Open, success')
|
||||
expect(gitLab.reviewLabel).toBe('PR #12 Open, success')
|
||||
expect(gitLab.reviewLabel).toBe('MR !12 Open, success')
|
||||
})
|
||||
|
||||
it('counts migration-unsupported agent entries by worktree id', () => {
|
||||
|
||||
Reference in New Issue
Block a user