awslabs / awslabs/filemoverexpress
[Feature] Support for selection of files/folders from multiple directories in a single transfer job
- Dominant language
- TypeScript
- Stars
- 4
- Forks
- 1
- Avg merge
- 9h 54m
- Merged PRs (30d)
- 41
Description
## 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.ts` — `selectedObjects` map, `clickFileBrowserRow`, `handleCmdClick`, `handleShiftClick`, `doubleClickRow`
- `src/cli/types/jobmanagertypes/job.go` — `Job` struct, `JobConfig`, `uploadBasePath` field
- `src/cli/core/upload/upload.go` — path resolution logic using `uploadBasePath`
- `src/cli/cmd/s3.go` — `uploadFile`, `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
Contributor guide
Research direction
Start with selectedObjects and the selection handlers in src/gui/src/app/components/layout/file-browser/file-browser.component.ts, then trace JobConfig and uploadBasePath through src/cli/types/jobmanagertypes/job.go and src/cli/core/upload/upload.go. Compare the absolute-path handling in src/cli/cmd/s3.go; done means cross-directory selections persist, can be individually removed, and produce consistent S3 paths without changing single-directory behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- aws, go, typescript
- Domain
- backend, cloud, frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100