Skip to content

Server form: extract useConnectionTest, useServerDelete and useIdentityFile hooks #857

Open

Description

@smart-ssh-planner

Goal

The three self-contained flows of the server form (connection test with host-key trust, delete with preview, identity-file checks and keychain conversion) each live in one hook, so the form component holds fewer unrelated states.

Context

apps/smart-ssh-community/frontend/src/components/ServerForm.tsx has 2,025 lines. The component function ServerForm spans :268–1997 with 55 useState and 10 useEffect. It renders two complete forms: the local pseudo-server (<Tabs at ~:1012, panels general :1020 and notes :1071) and a remote server (<Tabs at ~:1116, panels general :1134, connection :1207, security :1709, notes :1942), plus extension tabs (renderExtensionPanels :451). State groups on develop: loading/dirty tracking (loaded, dirty :283–286, loadServer :509, buildInput :687, handleSubmit :718, save :747); field values (name, host, port, username, groupId, jumpHost, tags, tagDraft, auth :342–350); identity file facts and keychain conversion (identityFacts* :355–362, convert* :366–370, handleConvertToKeychain :824, key-import prompt importPromptOpen/importError/importSavedId :401–405, finishKeepingPath :786); sudo password (:373–379, handleClearSudoPassword :794); security policy (postIngestPolicy, aiInjectionCheckEnabled, secondOpinionAvailable :380–391); tabs and validation (requestedTab, openedExtTabs, invalidTabs, reportValidityPending, tabsServerId :413–420, collectInvalidTabs :467); delete (deleting, deletePreview, secretsLeftBehind :489–495, handleDeleteClick :845, handleConfirmDelete :855); connection test (testing, testResult, testDialog, pendingHostKey :497–504, runTest :877, cancelTest :921, closeTestDialog :929, handleTrustAndRetest :934); local notes and tags (:293–321, :956–984). Helpers before the component: authKindLabels, AuthFormState, authStateFromKind, toAuthMethodInput, IdentityFileFacts (:80–267); exported TestResultBadge (:1997, imported by TestConnectionDialog.tsx). Tests: ServerForm.test.tsx and 7 ServerForm.*.test.tsx files (about 63 tests). Line numbers are from develop before the colour-token migration and may shift slightly.

End state of the series: no file over 800 lines, no function component over 400 lines, at most 12 useState per component; parts under src/components/serverForm/.

Requirements

  • src/components/serverForm/useConnectionTest.ts: testing, testResult, testDialog, pendingHostKey, runTest, cancelTest, closeTestDialog, handleTrustAndRetest.
  • src/components/serverForm/useServerDelete.ts: deleting, deletePreview, secretsLeftBehind, handleDeleteClick, handleConfirmDelete.
  • src/components/serverForm/useIdentityFile.ts: identity file facts (loading, error, debounced check), keychain conversion state and handler, and the key-import prompt state with finishKeepingPath.
  • The hooks receive what they need (server id, current input via a getter, callbacks such as onDeleted) as parameters; they do not read the form's other state directly.
  • Move IdentityFileFacts to src/components/serverForm/IdentityFileFacts.tsx and TestResultBadge to src/components/serverForm/TestResultBadge.tsx (re-export from ServerForm.tsx or update TestConnectionDialog.tsx).

Acceptance Criteria

  • The three hooks exist under src/components/serverForm/ with hook tests (renderHook): connection test success, failure and host-key prompt → trust → retest; delete preview → confirm → callback, delete error; identity file check success, check failure, conversion success and error.
  • ServerForm has at least 18 fewer useState calls than before this issue.
  • The test count of ServerForm*.test.tsx (plus the new hook tests) is not lower than before; existing tests pass without changes to their assertions.
  • npm run lint, npx vitest run, npm run build and npm run test:e2e pass.

Technical Notes

  • Pure refactoring: no change to behaviour, visible text, i18n keys, CSS classes, data-testids, ARIA attributes, keyboard handling, invoked Tauri commands or listened events. Behaviour changes, if you find a bug, go into a separate issue (mention it in the PR).

  • Colour classes in these files are being migrated to theme tokens in a separate issue that must be merged first; keep exactly the classes that are on develop when you start.

  • Exports that other files or tests import from the original file keep working: either update the importers or re-export from the original path. The extension API (src/extensions/*, src/api.ts, src/components/ui) does not change.

  • Tests: count it(/test( in the listed test files before and after; the number must not decrease. Tests may move next to an extracted unit, but their assertions stay the same. Tests drive the user-visible behaviour through FileBrowserPanel/ChatPanel/ServerForm as today.

  • New code comments in English; existing German comments may move unchanged.

  • No filter, risk, redaction or credential logic is touched (frontend only).

  • Gate: npm run lint, npx vitest run, npm run build in apps/smart-ssh-community/frontend, plus npm run test:e2e if a browser test covers the component.

  • Host-key trust in the connection test is security-relevant: the hook must call exactly the same API as today, only after the user's explicit "trust" decision.

Spec impact: none

Related Work

Activity

  1. added this to the 0.8.0 milestone on Oct 26, 2026
  2. 21 remaining items

  3. marked this as blocking 15 issues on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    frontendFrontend (React/TypeScript)

    Type

    Fields

    Priority

    P2 - Normal

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions