Repository navigation
File browser: extract useSftpTransfers and useElevation hooks from FileBrowserPanel #825
Description
Goal
Uploads/downloads with progress and conflicts, and the elevated (sudo) browsing mode, each live in one hook, so their state transitions can be read and tested in isolation.
Context
apps/smart-ssh-community/frontend/src/components/FileBrowserPanel.tsx has 3,634 lines. The component function FileBrowserPanel alone spans lines 206–2845 (logic 206–1646, JSX 1646–2845) with 51 useState, 29 useRef and 23 useEffect. Eight sub-components follow in the same file: FileEntryMenu (:2864), FilePropertiesDialog (:2991), ColumnsMenu (:3050), ChmodDialog (:3114), ChownDialog (:3292), RenamePrompt (:3390, with isValidEntryName :3456), DirectoryMenu (:3463), ColumnResizeHandle (:3552), ElevationFailureDialog (:3577); helpers findMenuTrigger/focusMenuTrigger (:2845–2863), formatMb, localDirName, revealLabelKey (:120–140). Tests: FileBrowserPanel.test.tsx (3,371 lines, 144 tests), FileBrowserPanel.android.test.tsx, FileBrowserPanel.startDirectory.test.tsx. Line numbers are from develop before the colour-token migration and may shift slightly.
Responsibilities to extract (state names as on develop):
- Transfers:
transfers,uploadConflict,folderConfirm,folderSummary,dragOver, theonSftpTransfer*event subscriptions, cancel, drop and folder upload. - Elevation:
elevation,enablingElevation,elevationTargetUser,otherUser*,elevationFailure,elevationWarning,stopPromptand the calls that enable/disable the elevated channel (about 84 occurrences of "elevat" in the file).
End state of the series: no file over 800 lines, no function component over 400 lines, at most 12 useState per component, sub-components and hooks under src/components/fileBrowser/.
Requirements
src/components/fileBrowser/useSftpTransfers.ts:useSftpTransfers(sessionId, …)owns the transfer list, conflicts and event subscriptions; it exposes start/cancel/resolve-conflict functions.src/components/fileBrowser/useElevation.ts:useElevation(sessionId)owns the elevation state, the enable/disable flow, the failure and warning state and the stop prompt for running elevated operations.- Event subscriptions keep their exact filter by session id and are cleaned up on unmount; the subscription effect of each hook depends only on the values it really needs.
- Hook unit tests with
renderHook: transfer progress event updates the matching transfer only, cancel, conflict resolution; elevation enable success, enable failure shows the failure state, disable with running operations asks first.
Acceptance Criteria
-
useSftpTransfersanduseElevationexist with unit tests (at least the cases listed above). -
FileBrowserPanelhas at most 20useStatecalls left. - Elevated mode still never applies to a different session than the one it was enabled for (existing tests pass unchanged).
- The test count of
FileBrowserPanel*.test.tsxis not lower than before; all pass. -
npm run lint,npx vitest run,npm run buildandnpm run test:e2epass.
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
developwhen 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 throughFileBrowserPanel/ChatPanel/ServerFormas 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 buildinapps/smart-ssh-community/frontend, plusnpm run test:e2eif a browser test covers the component. -
The elevated channel is enforced in the backend; the frontend only requests it. Do not change which commands are invoked with an elevated user or when.
Spec impact: none
Related Work
- Previous: File browser: move the sub-components out of FileBrowserPanel.tsx into components/fileBrowser/ #819, File browser: extract FileTable, FileToolbar, TransferList and ElevationControls from FileBrowserPanel #821, File browser: extract useRemoteDirectory and useFileColumns hooks from FileBrowserPanel #824; next: File browser: useFileOperations reducer for dialog state; FileBrowserPanel within the size limits #827
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity
21 remaining items