Skip to content

File browser: extract useRemoteDirectory and useFileColumns hooks from FileBrowserPanel #824

Open

Description

@smart-ssh-planner

Goal

Loading and navigating a remote directory, and the column/sort layout of the file table, each live in one hook with a clear interface instead of being spread over FileBrowserPanel's state and effects.

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):

  1. Directory loading and navigation: path, pathInput, startPath, rawEntries, loading, error, load, handleRefresh, start-directory handling, reload on elevation change.
  2. Sorting and columns: fileSort (loaded once on mount ~:649, handleSortClick ~:654, persisted via saveFileManagerSort in src/layoutSettings.ts), hiddenColumns, columnsMenu, columnWidths, handleColumnDrag.

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/useRemoteDirectory.ts: useRemoteDirectory(sessionId, elevatedUser, options) returning the current path, entries, loading/error state and load/refresh/navigateUp (names your choice). It owns the related state and effects.
  • src/components/fileBrowser/useFileColumns.ts: useFileColumns() returning sort, hidden columns, widths and their handlers, including persistence through the existing layoutSettings.ts functions.
  • FileBrowserPanel uses both hooks; the moved useState/useEffect calls disappear from it.
  • Hook unit tests with @testing-library/react's renderHook: directory load success, load error, refresh keeps the path; sort toggle and persistence, hidden column toggle.

Acceptance Criteria

  • useRemoteDirectory and useFileColumns exist with unit tests (at least the cases listed above).
  • FileBrowserPanel has at least 10 fewer useState calls than before this issue.
  • The test count of FileBrowserPanel*.test.tsx is not lower than before; all 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.

  • Propagate file browser sort changes to all open panels #747 (sort changes propagate to all open panels) touches the sort state; if it is merged first, useFileColumns takes over its mechanism unchanged.

  • Keep the order in which effects run on mount (start directory, then first load) as today; tests in FileBrowserPanel.startDirectory.test.tsx cover it.

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