Skip to content

[Feature] Support for selection of files/folders from multiple directories in a single transfer job #9

Description

@therangerangler

Summary

Allow users to select files and folders from multiple directories as part of a single transfer job. Currently, navigating away from a directory clears the selection, forcing users to transfer one directory at a time.

Current behavior

In the GUI file browser, selections are stored in a selectedObjects map keyed by filename (row.name). When the user navigates into a subdirectory or back up to a parent, the selection is cleared. There is no way to accumulate a selection across multiple directories before starting a transfer.

On the backend, a Job has a single uploadBasePath field alongside a sources slice. The upload logic in src/cli/core/upload/upload.go resolves all source paths relative to this single base path. This means all selected files must share a common root directory — files from unrelated directories cannot be combined into one job without losing their path context.

Desired behavior

Users should be able to:

  1. Select files/folders in one directory
  2. Navigate to another directory and add more files/folders to the selection
  3. Start a single transfer job containing all selected items regardless of where they came from

File path integrity must be preserved — the S3 destination path for each file should reflect its original directory structure relative to the transfer destination, not be flattened.

Example

A user wants to upload:

/Volumes/Media/ProjectA/footage/scene1.mov
/Volumes/Media/ProjectA/audio/mix_v2.wav
/Volumes/Media/ProjectB/exports/final.mov

These come from three different directories. Today this requires three separate transfer jobs. With this feature, one job handles all three, and the S3 structure mirrors the source paths.

What needs to change

GUI (src/gui/src/app/components/layout/file-browser/):

  • The selectedObjects map is currently scoped to the active directory view and cleared on navigation. It needs to become a persistent cross-directory selection, keyed by full absolute path rather than just filename.
  • A selection panel or indicator should show the user what is currently queued across directories, with the ability to remove individual items.
  • Navigating directories should not clear the accumulated selection.

Backend (src/cli/types/jobmanagertypes/job.go and src/cli/core/upload/upload.go):

  • JobConfig.UploadBasePath is a single string representing the common root for all sources. This assumption breaks when sources come from different directories.
  • The upload logic in upload.go resolves relative paths against UploadBasePath using filepath.Join. For multi-directory selections, each source needs to carry its own base path context, or sources must always be passed as absolute paths.
  • The CLI upload command already handles absolute paths correctly — fs.LongestCommonDirectories(sources) is used to find a common base. This approach could be extended, but care is needed to ensure the S3 destination structure is preserved correctly when there is no meaningful common root.

File path integrity

When files from different directories are combined into one job, the S3 destination paths must preserve the original directory structure. For example, uploading the three files above to an S3 prefix projects/ should produce:

s3://bucket/projects/Volumes/Media/ProjectA/footage/scene1.mov
s3://bucket/projects/Volumes/Media/ProjectA/audio/mix_v2.wav
s3://bucket/projects/Volumes/Media/ProjectB/exports/final.mov

Or, if a common root is detected (/Volumes/Media/), strip it:

s3://bucket/projects/ProjectA/footage/scene1.mov
s3://bucket/projects/ProjectA/audio/mix_v2.wav
s3://bucket/projects/ProjectB/exports/final.mov

The chosen behaviour should be consistent and clearly communicated to the user before the transfer starts.

Relevant files

  • src/gui/src/app/components/layout/file-browser/file-browser.component.tsselectedObjects map, clickFileBrowserRow, handleCmdClick, handleShiftClick, doubleClickRow
  • src/cli/types/jobmanagertypes/job.goJob struct, JobConfig, uploadBasePath field
  • src/cli/core/upload/upload.go — path resolution logic using uploadBasePath
  • src/cli/cmd/s3.gouploadFile, fs.LongestCommonDirectories usage for absolute path handling

Acceptance criteria

  • Users can select files and folders from multiple directories before starting a transfer
  • Navigating between directories does not clear the accumulated selection
  • A persistent selection indicator shows what is queued, with the ability to remove individual items
  • File path integrity is preserved in the S3 destination structure
  • The existing single-directory selection behaviour is unchanged for users who do not navigate between directories

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions