mirror of
https://github.com/stablyai/orca.git
synced 2026-10-23 08:03:39 +00:00
fix(cmd-j): restore host badges
This commit is contained in:
@@ -8,7 +8,7 @@ import type * as ReactI18Next from 'react-i18next'
|
||||
import { useAppStore } from '@/store'
|
||||
import type { AppState } from '@/store/types'
|
||||
import WorktreeJumpPalette from './WorktreeJumpPalette'
|
||||
import { makeRepo, makeWorktree } from './worktree-jump-palette-test-fixtures'
|
||||
import { makeRecentTabState, makeRepo, makeWorktree } from './worktree-jump-palette-test-fixtures'
|
||||
|
||||
const { activateAndRevealWorktree } = vi.hoisted(() => ({
|
||||
activateAndRevealWorktree: vi.fn(() => false)
|
||||
@@ -48,9 +48,10 @@ vi.mock('@/components/repo/RepoBadgeLabel', () => ({
|
||||
RepoBadgeMark: () => <span data-repo-badge-mark="true" />
|
||||
}))
|
||||
|
||||
vi.mock('@/components/cmd-j/palette-host-badge', () => ({
|
||||
getPaletteHostBadge: () => null
|
||||
const { getPaletteHostBadge } = vi.hoisted(() => ({
|
||||
getPaletteHostBadge: vi.fn(() => null as { hostId: 'local'; label: string } | null)
|
||||
}))
|
||||
vi.mock('@/components/cmd-j/palette-host-badge', () => ({ getPaletteHostBadge }))
|
||||
|
||||
// Why: activation reaches into window.api and the whole worktree-reveal path; the palette's own
|
||||
// contract is which result it hands over, so stub the boundary and assert on that.
|
||||
@@ -191,6 +192,7 @@ describe('WorktreeJumpPalette', () => {
|
||||
globalThis.IS_REACT_ACT_ENVIRONMENT = true
|
||||
setCommandQuery = null
|
||||
activateAndRevealWorktree.mockClear()
|
||||
getPaletteHostBadge.mockReturnValue(null)
|
||||
useAppStore.setState(initialAppState, true)
|
||||
testContainer = document.createElement('div')
|
||||
document.body.appendChild(testContainer)
|
||||
@@ -230,6 +232,17 @@ describe('WorktreeJumpPalette', () => {
|
||||
expect(testContainer.textContent).toContain('Folder workspace')
|
||||
})
|
||||
|
||||
it('renders the owning host badge on worktree and tab rows', async () => {
|
||||
getPaletteHostBadge.mockReturnValue({ hostId: 'local', label: 'Local Mac' })
|
||||
await renderPalette(makeRecentTabState())
|
||||
|
||||
const badge = '[aria-label="Host: Local Mac"]'
|
||||
expect(testContainer.querySelector(`[data-command-item*="worktree:"] ${badge}`)).not.toBeNull()
|
||||
expect(
|
||||
testContainer.querySelector(`[data-command-item*="workspace-tab:"] ${badge}`)
|
||||
).not.toBeNull()
|
||||
})
|
||||
|
||||
it('keeps the explicit default-branch filter authoritative', async () => {
|
||||
const defaultBranch = makeWorktree('default-branch', 'Default branch workspace', {
|
||||
isMainWorktree: true,
|
||||
|
||||
@@ -141,6 +141,7 @@ import {
|
||||
import { RepoBadgeMark } from '@/components/repo/RepoBadgeLabel'
|
||||
import { buildSidebarHostOptions } from '@/components/sidebar/sidebar-host-options'
|
||||
import { getPaletteHostBadge } from '@/components/cmd-j/palette-host-badge'
|
||||
import PaletteHostBadgeChip from '@/components/cmd-j/PaletteHostBadgeChip'
|
||||
import { getWorktreeHostIdentity } from '../../../shared/worktree/host-qualified-identity'
|
||||
import { getRepoHostIdentity } from '@/store/slices/repo-host-identity'
|
||||
import type { Repo } from '../../../shared/repo-types'
|
||||
@@ -3221,6 +3222,7 @@ function WorktreeJumpPaletteContent({
|
||||
: null
|
||||
const isSshDisconnected = sshStatus != null && sshStatus !== 'connected'
|
||||
const sessionAge = formatPaletteSessionAge(worktree.lastActivityAt, paletteNowMs)
|
||||
const hostBadge = getPaletteHostBadge(repo, hostOptions, hostFilterActive)
|
||||
return (
|
||||
<CommandItem
|
||||
key={renderKey}
|
||||
@@ -3329,6 +3331,7 @@ function WorktreeJumpPaletteContent({
|
||||
)}
|
||||
</div>
|
||||
<div className="flex shrink-0 items-center gap-1.5">
|
||||
<PaletteHostBadgeChip badge={hostBadge} />
|
||||
{repoName && (
|
||||
<span className="inline-flex max-w-[180px] items-center gap-1.5 rounded-md border border-border bg-muted px-2 py-1 text-[11px] font-semibold leading-none text-foreground">
|
||||
<RepoBadgeMark color={repo?.badgeColor} />
|
||||
@@ -3350,6 +3353,9 @@ function WorktreeJumpPaletteContent({
|
||||
if (entry.type === 'project-target') {
|
||||
const result = entry.result
|
||||
const isProject = result.kind === 'project'
|
||||
const hostBadge = isProject
|
||||
? getPaletteHostBadge(result.repo, hostOptions, hostFilterActive)
|
||||
: null
|
||||
const badgeLabel = isProject
|
||||
? translate('auto.components.WorktreeJumpPalette.projectBadge', 'Project')
|
||||
: translate('auto.components.WorktreeJumpPalette.repoGroupBadge', 'Repo group')
|
||||
@@ -3377,6 +3383,7 @@ function WorktreeJumpPaletteContent({
|
||||
</div>
|
||||
{isProject ? (
|
||||
<div className="flex shrink-0 items-center gap-1.5">
|
||||
<PaletteHostBadgeChip badge={hostBadge} />
|
||||
<span className="inline-flex max-w-[180px] items-center gap-1.5 rounded-md border border-border bg-muted px-2 py-1 text-[11px] font-semibold leading-none text-foreground">
|
||||
<RepoBadgeMark color={result.repo.badgeColor} />
|
||||
<span className="truncate">{result.repo.displayName}</span>
|
||||
@@ -3434,6 +3441,11 @@ function WorktreeJumpPaletteContent({
|
||||
? resolveRepoForWorktree(workspaceTabWorktree)
|
||||
: undefined
|
||||
const workspaceTabRepoName = workspaceTabRepo?.displayName ?? result.repoName
|
||||
const workspaceTabHostBadge = getPaletteHostBadge(
|
||||
workspaceTabRepo,
|
||||
hostOptions,
|
||||
hostFilterActive
|
||||
)
|
||||
const workspaceTabFallback =
|
||||
result.contentType === 'terminal' && result.occupantAgent ? (
|
||||
<span
|
||||
@@ -3500,6 +3512,7 @@ function WorktreeJumpPaletteContent({
|
||||
worktree={workspaceTabWorktree}
|
||||
className="max-w-[280px] truncate text-[12px] font-medium text-muted-foreground"
|
||||
/>
|
||||
<PaletteHostBadgeChip badge={workspaceTabHostBadge} />
|
||||
{workspaceTabRepoName && (
|
||||
<span className="inline-flex max-w-[180px] items-center gap-1.5 rounded-md border border-border bg-muted px-2 py-1 text-[11px] font-semibold leading-none text-foreground">
|
||||
<RepoBadgeMark color={workspaceTabRepo?.badgeColor} />
|
||||
@@ -3529,6 +3542,11 @@ function WorktreeJumpPaletteContent({
|
||||
? resolveRepoForWorktree(simulatorWorktree)
|
||||
: undefined
|
||||
const simulatorRepoName = simulatorRepo?.displayName ?? result.repoName
|
||||
const simulatorHostBadge = getPaletteHostBadge(
|
||||
simulatorRepo,
|
||||
hostOptions,
|
||||
hostFilterActive
|
||||
)
|
||||
const sessionAge = formatPaletteSessionAge(
|
||||
result.lastActiveAt ?? null,
|
||||
paletteNowMs
|
||||
@@ -3582,6 +3600,7 @@ function WorktreeJumpPaletteContent({
|
||||
worktree={simulatorWorktree}
|
||||
className="max-w-[280px] truncate text-[12px] font-medium text-muted-foreground"
|
||||
/>
|
||||
<PaletteHostBadgeChip badge={simulatorHostBadge} />
|
||||
{simulatorRepoName && (
|
||||
<span className="inline-flex max-w-[180px] items-center gap-1.5 rounded-md border border-border bg-muted px-2 py-1 text-[11px] font-semibold leading-none text-foreground">
|
||||
<RepoBadgeMark color={simulatorRepo?.badgeColor} />
|
||||
@@ -3610,6 +3629,11 @@ function WorktreeJumpPaletteContent({
|
||||
? resolveRepoForWorktree(browserWorktree)
|
||||
: undefined
|
||||
const browserRepoName = browserRepo?.displayName ?? result.repoName
|
||||
const browserHostBadge = getPaletteHostBadge(
|
||||
browserRepo,
|
||||
hostOptions,
|
||||
hostFilterActive
|
||||
)
|
||||
const sessionAge = formatPaletteSessionAge(result.lastActiveAt ?? null, paletteNowMs)
|
||||
|
||||
return (
|
||||
@@ -3660,6 +3684,7 @@ function WorktreeJumpPaletteContent({
|
||||
worktree={browserWorktree}
|
||||
className="max-w-[280px] truncate text-[12px] font-medium text-muted-foreground"
|
||||
/>
|
||||
<PaletteHostBadgeChip badge={browserHostBadge} />
|
||||
{browserRepoName && (
|
||||
<span className="inline-flex max-w-[180px] items-center gap-1.5 rounded-md border border-border bg-muted px-2 py-1 text-[11px] font-semibold leading-none text-foreground">
|
||||
<RepoBadgeMark color={browserRepo?.badgeColor} />
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { translate } from '@/i18n/i18n'
|
||||
import type { PaletteHostBadge } from './palette-host-badge'
|
||||
|
||||
export default function PaletteHostBadgeChip({
|
||||
badge
|
||||
}: {
|
||||
badge: PaletteHostBadge | null
|
||||
}): React.JSX.Element | null {
|
||||
if (!badge) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<span
|
||||
aria-label={translate(
|
||||
'auto.components.WorktreeJumpPalette.paletteHostBadge',
|
||||
'Host: {{value0}}',
|
||||
{ value0: badge.label }
|
||||
)}
|
||||
className="max-w-[140px] truncate rounded-[6px] border border-border/60 bg-background px-1.5 py-px text-[9px] font-medium leading-normal text-muted-foreground/88"
|
||||
>
|
||||
{badge.label}
|
||||
</span>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user