mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-16 13:03:31 +08:00
fix: keep launch context rail on one line
Long branch names should be clipped inside the branch selector instead of forcing the repository context rail onto a second row. The rail now stays nowrap, the branch selector owns truncation, and the worktree mode selector keeps its readable fixed footprint. Constraint: Preserve the existing composer and repository context layout shape. Rejected: Let the rail wrap on long branch names | it creates the broken two-line state shown in the desktop composer. Confidence: high Scope-risk: narrow Directive: Long repository or branch labels must truncate inside their own controls rather than changing the rail height. Tested: cd desktop && bun run test -- --run src/pages/EmptySession.test.tsx src/components/chat/ChatInput.test.tsx src/components/shared/DirectoryPicker.test.tsx Tested: bun run check:desktop Tested: agent-browser selected a long branch on http://localhost:4790 and verified rail height 53px, branch width 260px, no horizontal overflow; screenshot /tmp/cc-haha-launch-rail-long-branch-nowrap.png Not-tested: Native Tauri packaged window visual check
This commit is contained in:
parent
5675539ef0
commit
5c738db3af
@ -298,11 +298,11 @@ export function RepositoryLaunchControls({
|
||||
}, [isLaunchReady, onLaunchReadyChange])
|
||||
|
||||
const worktreeLabel = useWorktree ? t('repoLaunch.worktreeIsolated') : t('repoLaunch.worktreeCurrent')
|
||||
const workbarButtonClassName = 'group inline-flex h-9 max-w-full min-w-0 items-center gap-1.5 rounded-[7px] border border-transparent px-2.5 text-[13px] font-medium leading-none text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-surface-container-lowest)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-brand)]/35 disabled:cursor-not-allowed disabled:opacity-50'
|
||||
const workbarButtonClassName = 'group inline-flex h-9 min-w-0 items-center gap-1.5 rounded-[7px] border border-transparent px-2.5 text-[13px] font-medium leading-none text-[var(--color-text-secondary)] transition-colors hover:bg-[var(--color-surface-container-lowest)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-brand)]/35 disabled:cursor-not-allowed disabled:opacity-50'
|
||||
|
||||
return (
|
||||
<div ref={rootRef} className="flex min-w-0 flex-col gap-2">
|
||||
<div className="flex min-h-[48px] min-w-0 flex-wrap items-center justify-start gap-x-1.5 gap-y-1 rounded-b-xl border-t border-[var(--color-border-separator)] bg-[var(--color-surface-container-low)] px-4 py-2 shadow-[inset_0_1px_0_rgba(255,255,255,0.45)]">
|
||||
<div className="flex min-h-[48px] min-w-0 flex-nowrap items-center justify-start gap-x-1.5 gap-y-1 overflow-hidden rounded-b-xl border-t border-[var(--color-border-separator)] bg-[var(--color-surface-container-low)] px-4 py-2 shadow-[inset_0_1px_0_rgba(255,255,255,0.45)]">
|
||||
<DirectoryPicker value={workDir} onChange={onWorkDirChange} variant="workbar" isGitProject={isGitReady} />
|
||||
|
||||
{loading && workDir && (
|
||||
@ -328,7 +328,7 @@ export function RepositoryLaunchControls({
|
||||
setWorktreeMenuOpen(false)
|
||||
setBranchFilter('')
|
||||
}}
|
||||
className={`${workbarButtonClassName} max-w-[260px]`}
|
||||
className={`${workbarButtonClassName} max-w-[260px] shrink`}
|
||||
>
|
||||
<GitBranch size={17} className="shrink-0 text-[var(--color-text-tertiary)] group-hover:text-[var(--color-text-secondary)]" />
|
||||
<span className="min-w-0 flex-1 truncate text-[var(--color-text-primary)]">
|
||||
@ -350,7 +350,7 @@ export function RepositoryLaunchControls({
|
||||
setWorktreeMenuOpen((prev) => !prev)
|
||||
setBranchMenuOpen(false)
|
||||
}}
|
||||
className={`${workbarButtonClassName} ${
|
||||
className={`${workbarButtonClassName} shrink-0 ${
|
||||
useWorktree
|
||||
? 'bg-[var(--color-surface-container-lowest)] text-[var(--color-text-primary)]'
|
||||
: ''
|
||||
|
||||
@ -304,6 +304,42 @@ describe('EmptySession', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps the repository launch context on one row and truncates long branch names', async () => {
|
||||
const longBranch = 'feature/super-long-branch-name-for-repository-launch-controls-e2e'
|
||||
mocks.getRepositoryContext.mockResolvedValueOnce(okRepositoryContext({
|
||||
currentBranch: longBranch,
|
||||
defaultBranch: 'main',
|
||||
branches: [{
|
||||
name: longBranch,
|
||||
current: true,
|
||||
local: true,
|
||||
remote: false,
|
||||
checkedOut: true,
|
||||
worktreePath: '/workspace/project',
|
||||
}],
|
||||
worktrees: [{
|
||||
path: '/workspace/project',
|
||||
branch: longBranch,
|
||||
current: true,
|
||||
}],
|
||||
}))
|
||||
|
||||
render(<EmptySession />)
|
||||
|
||||
fireEvent.change(screen.getByRole('textbox'), {
|
||||
target: { value: 'draft question', selectionStart: 14 },
|
||||
})
|
||||
fireEvent.click(screen.getByRole('button', { name: 'Pick project' }))
|
||||
|
||||
const branchButton = await screen.findByRole('button', { name: new RegExp(`Select branch: ${longBranch}`) })
|
||||
const branchClasses = branchButton.className.split(/\s+/)
|
||||
expect(branchButton.parentElement?.className).toContain('flex-nowrap')
|
||||
expect(branchButton.parentElement?.className).not.toContain('flex-wrap')
|
||||
expect(branchClasses).toContain('max-w-[260px]')
|
||||
expect(branchClasses).not.toContain('max-w-full')
|
||||
expect(branchButton.querySelector('span')?.className).toContain('truncate')
|
||||
})
|
||||
|
||||
it('defaults to isolated worktree when the fallback branch is checked out elsewhere', async () => {
|
||||
mocks.getRepositoryContext.mockResolvedValueOnce(okRepositoryContext({
|
||||
currentBranch: null,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user