diff --git a/src/main/ssh/orcad-migration-conflict-guidance.test.ts b/src/main/ssh/orcad-migration-conflict-guidance.test.ts new file mode 100644 index 00000000000..a9c4e942be7 --- /dev/null +++ b/src/main/ssh/orcad-migration-conflict-guidance.test.ts @@ -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() + }) +}) diff --git a/src/renderer/src/components/plain-ssh-terminal/OpenPlainSshTerminalButton.tsx b/src/renderer/src/components/plain-ssh-terminal/OpenPlainSshTerminalButton.tsx index 75f6197a195..8d3a7b8c7f7 100644 --- a/src/renderer/src/components/plain-ssh-terminal/OpenPlainSshTerminalButton.tsx +++ b/src/renderer/src/components/plain-ssh-terminal/OpenPlainSshTerminalButton.tsx @@ -23,13 +23,22 @@ export function OpenPlainSshTerminalButton({ return null } return ( - + + + {/* The next step for any block, including ones retrying can't clear. */} + + {translate( + 'auto.components.plainSshTerminal.openHint', + 'Keeps you working on the host while Orca can’t set up there.' + )} + + ) } diff --git a/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.test.tsx b/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.test.tsx index c653b30619c..bf8e667e4d3 100644 --- a/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.test.tsx +++ b/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.test.tsx @@ -241,6 +241,7 @@ describe('plain SSH terminal', () => { render() 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 () => { diff --git a/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.tsx b/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.tsx index 638efb15489..e9404d35602 100644 --- a/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.tsx +++ b/src/renderer/src/components/plain-ssh-terminal/PlainSshTerminalPanels.tsx @@ -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 ? (

{message}

) : null} -
+ {/* An empty terminal under a failed open's error would read as a live session. */} +