mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(ssh): say what plain SSH is for beside its button, and polish the plain SSH window (#31732)
* fix(ssh): point unclearable move conflicts at plain SSH, and polish the plain SSH window Conflicts retrying can't clear now say how to keep working on the host. The plain SSH terminal paints its theme background past the grid, and a failed open shows only its error, not an empty terminal. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): say what plain SSH is for beside its button, not in main's refusal text Main's refusal text also reaches clients without a plain SSH terminal, so the next step is shown next to the button wherever it renders. Also: a translucent theme isn't painted twice, and a failed open shrinks to its error. Co-Authored-By: Claude <noreply@anthropic.com> * fix(ssh): treat only opacity below 1 as a translucent plain SSH background Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { orcadMigrationConflictGuidance } from './orcad-migration-conflict-guidance'
|
||||
|
||||
const NO_DESKTOP_STEP = [
|
||||
'project_group_id',
|
||||
'folder_workspace_id',
|
||||
'dormant_id',
|
||||
'dormant_focus',
|
||||
'client_state',
|
||||
'close_intent_destination',
|
||||
'snapshot_destination'
|
||||
]
|
||||
|
||||
describe('orcad migration conflict guidance', () => {
|
||||
// Why no UI words here: this text also reaches clients that have no plain SSH terminal.
|
||||
it('names the code for every conflict retrying can’t clear, and no client-only action', () => {
|
||||
for (const kind of NO_DESKTOP_STEP) {
|
||||
const text = orcadMigrationConflictGuidance(
|
||||
new Error(`orcad_migration_${kind}_conflict:ui:workspaceHostScope`)
|
||||
)
|
||||
expect(text).toContain('Retrying won’t clear it.')
|
||||
expect(text).not.toContain('plain SSH')
|
||||
expect(text).toContain(`orcad_migration_${kind}_conflict`)
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps the specific way out where the desktop has one', () => {
|
||||
expect(
|
||||
orcadMigrationConflictGuidance(
|
||||
new Error('orcad_migration_repository_path_conflict:/home/me/app')
|
||||
)
|
||||
).toContain('remove that project from this desktop and connect again')
|
||||
})
|
||||
|
||||
it('is null for anything that is not a conflict', () => {
|
||||
expect(orcadMigrationConflictGuidance(new Error('ECONNRESET'))).toBeNull()
|
||||
})
|
||||
})
|
||||
@@ -23,13 +23,22 @@ export function OpenPlainSshTerminalButton({
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<Button
|
||||
type="button"
|
||||
size="xs"
|
||||
variant="outline"
|
||||
onClick={() => showPlainSshPanel(targetId, targetLabel)}
|
||||
>
|
||||
{translate('auto.components.plainSshTerminal.open', 'Open plain SSH terminal')}
|
||||
</Button>
|
||||
<span className="inline-flex flex-wrap items-center gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
size="xs"
|
||||
variant="outline"
|
||||
onClick={() => showPlainSshPanel(targetId, targetLabel)}
|
||||
>
|
||||
{translate('auto.components.plainSshTerminal.open', 'Open plain SSH terminal')}
|
||||
</Button>
|
||||
{/* The next step for any block, including ones retrying can't clear. */}
|
||||
<span className="text-xs text-muted-foreground">
|
||||
{translate(
|
||||
'auto.components.plainSshTerminal.openHint',
|
||||
'Keeps you working on the host while Orca can’t set up there.'
|
||||
)}
|
||||
</span>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -241,6 +241,7 @@ describe('plain SSH terminal', () => {
|
||||
render(<Harness status={blocked} />)
|
||||
await user.click(screen.getByRole('button', { name: 'Open plain SSH terminal' }))
|
||||
expect(await screen.findByText(/couldn’t find OpenSSH/)).toBeInTheDocument()
|
||||
expect(document.querySelector('[data-plain-ssh-screen]')).toHaveClass('hidden')
|
||||
})
|
||||
|
||||
it('hangs up when its window closes', async () => {
|
||||
|
||||
@@ -76,6 +76,8 @@ function PlainSshTerminalCard({ panel }: { panel: PlainSshPanel }): React.JSX.El
|
||||
// Why hidden, not unmounted: minimizing must keep the SSH session and its scrollback.
|
||||
className={cn(
|
||||
'pointer-events-auto flex h-[26rem] w-[min(44rem,calc(100vw-2rem))] flex-col overflow-hidden rounded-xl border border-border bg-card text-card-foreground shadow-floating',
|
||||
// A failed open has only its error to show.
|
||||
phase.kind === 'failed' && 'h-auto',
|
||||
panel.minimized && 'hidden'
|
||||
)}
|
||||
>
|
||||
@@ -105,7 +107,11 @@ function PlainSshTerminalCard({ panel }: { panel: PlainSshPanel }): React.JSX.El
|
||||
{message ? (
|
||||
<p className="px-3 py-1.5 text-xs text-destructive [overflow-wrap:anywhere]">{message}</p>
|
||||
) : null}
|
||||
<div className="min-h-0 flex-1">
|
||||
{/* An empty terminal under a failed open's error would read as a live session. */}
|
||||
<div
|
||||
data-plain-ssh-screen
|
||||
className={cn('min-h-0 flex-1', phase.kind === 'failed' && 'hidden')}
|
||||
>
|
||||
<PlainSshTerminalView
|
||||
targetId={panel.targetId}
|
||||
hidden={panel.minimized}
|
||||
|
||||
@@ -314,5 +314,18 @@ export function PlainSshTerminalView({
|
||||
}
|
||||
}, [hidden])
|
||||
|
||||
return <div ref={containerRef} className="size-full min-h-0 overflow-hidden px-2 py-1" />
|
||||
// Why the theme's background: fit leaves a remainder of pixels beside the grid that must not show the card.
|
||||
const themeBackground = resolveThemeColors(settings, systemPrefersDark).theme?.background
|
||||
// A translucent theme is painted once by xterm already; painting it again would darken the grid.
|
||||
// Same test as xterm's allowTransparency (preview-terminal-options), not the rgba form opacity 1 also takes.
|
||||
const translucent =
|
||||
settings?.terminalBackgroundOpacity !== undefined && settings.terminalBackgroundOpacity < 1
|
||||
const background = translucent ? undefined : themeBackground
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="size-full min-h-0 overflow-hidden px-2 py-1"
|
||||
style={background ? { backgroundColor: background } : undefined}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18598,7 +18598,8 @@
|
||||
"alreadyOpen": "Another Orca window already has a plain SSH terminal open to this host.",
|
||||
"endedBySignal": "ssh was stopped (signal {{signal}}). Close this window when you’re done reading.",
|
||||
"cancelled": "This plain SSH terminal was closed before it started.",
|
||||
"terminalUnavailable": "Orca couldn’t open a terminal here."
|
||||
"terminalUnavailable": "Orca couldn’t open a terminal here.",
|
||||
"openHint": "Keeps you working on the host while Orca can’t set up there."
|
||||
}
|
||||
},
|
||||
"i18n": {
|
||||
|
||||
Reference in New Issue
Block a user