Feature #19378
closedCan select folder to recursively upload all the files to Collection
Description
Currently, users can select multiple files to upload at once, but cannot select folders to upload a directory of files preserving hierarchy.
For this ticket:
- Users should be able to select folders
- Folders are uploaded preserving subdirectory layout
Some potentially useful reading: https://stackoverflow.com/questions/55608472/how-can-we-simply-upload-folder-in-reactjs
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-08-31 sprint to 2022-09-14 sprint
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-09-14 sprint to 2022-09-28 sprint
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-09-28 sprint to 2022-10-26 sprint
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-10-26 sprint to 2022-11-09 sprint
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-11-09 sprint to 2022-11-23 sprint
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-11-23 sprint to 2022-12-07 Sprint
Updated by Peter Amstutz over 3 years ago
- Is duplicate of Support #15197: [Data operation] Folders upload added
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-12-07 Sprint to 2022-12-21 Sprint
Updated by Peter Amstutz over 3 years ago
- Target version changed from 2022-12-21 Sprint to 2023-01-18 sprint
Updated by Peter Amstutz about 3 years ago
- Target version changed from 2023-01-18 sprint to 2023-02-01 sprint
Updated by Peter Amstutz about 3 years ago
- Release set to 59
- Target version deleted (
2023-02-01 sprint)
Updated by Peter Amstutz about 3 years ago
- Target version set to To be scheduled
Updated by Peter Amstutz almost 3 years ago
- Target version changed from To be scheduled to Development 2023-04-26 sprint
Updated by Peter Amstutz almost 3 years ago
- Status changed from New to Duplicate
Updated by Peter Amstutz almost 3 years ago
- Status changed from Duplicate to New
Updated by Peter Amstutz almost 3 years ago
- Target version changed from Development 2023-04-26 sprint to Development 2023-05-10 sprint
Updated by Peter Amstutz almost 3 years ago
- Target version changed from Development 2023-05-10 sprint to To be scheduled
Updated by Peter Amstutz over 2 years ago
- Target version changed from To be scheduled to Development 2023-09-13 sprint
Updated by Peter Amstutz over 2 years ago
- Target version changed from Development 2023-09-13 sprint to Development 2023-09-27 sprint
Updated by Peter Amstutz over 2 years ago
- Target version changed from Development 2023-09-27 sprint to To be scheduled
Updated by Peter Amstutz about 2 years ago
- Target version changed from To be scheduled to Future
Updated by Peter Amstutz 12 months ago
- Related to Bug #16170: Uploading of folder structure into collection is not working added
Updated by Lisa Knox 11 months ago
After some research, it looks like the package we use for uploading files in this form, react-dropzone, does not support folder uploading. The package https://www.npmjs.com/package/@rpldy/uploady looks like it will suit our needs.
Updated by Brett Smith 9 months ago
- Target version changed from Future to Development 2025-07-09
- Status changed from New to In Progress
Updated by Lisa Knox 9 months ago
19378-folder-upload @ a0bcc6910900b8f80659923bd105cce6e833c562
developer-run-tests-services-workbench2: #1542
- ✅ All agreed upon points are implemented / addressed.
- ✅ Anything not implemented (discovered or discussed during work) has a follow-up story.
- ✅ Code is tested and passing, both automated and manual, what manual testing was done is described
- ✅ Documentation has been updated.
- ✅ Behaves appropriately at the intended scale (describe intended scale).
- creating multiple nested dirs is a bit slow, but the slowness is all in the network requests, so without a new endpoint to create multiple dirs at once, the slowness is what it is
- ✅ Considered backwards and forwards compatibility issues between client and server.
- ✅ Follows our coding standards and GUI style guidelines.
- It turns out that while Uploady would meet our needs, using it would require us to rewrite a substantial part of the upload interface to get it to work with Redux Form. Writing the components from scratch was the simplest solution, so that's what I did, which also removes our dependency on react-dropzone.
- There are now two clickable fields within the drag-and-drop field, because browsers do not support a single element that can open a combined folder/file selector.
- The drag-and drop field itself now supports both file and folder drops, except on certain firefox versions that do not support it (such as Mozilla Firefox Flatpak v140.0.2 (64-bit)).
- Folder drops retain nested file structure
- Cypress does not support uploading folders, so the best test I could make is to simulate creating nested dirs without any content
Updated by Brett Smith 9 months ago
- Target version changed from Development 2025-07-09 to Development 2025-07-23
Updated by Stephen Smith 8 months ago
So I did some more investigation and discovered that:
- Like i suspected, you can't replace_files a parent folder with the empty collection uuid to create a directory followed by a subdirectory in the same request, but since you can directly replace_files a nonexistant nested path with the empty collection uuid, this doesn't really matter - this allows creating all the directories in a single request as long as you only give it terminal paths
- You can use preserve_version=false to avoid versioning the directory changes, so that the following file upload results in a single version change with the new directories
So I have these recommendations:
- I noticed that
getMinNecessaryPathsdoesn't actually filter out parent folder paths, sinceuniquePaths.some((existing) => path === existingwill always be true because path is an anumeration of uniquePaths sopath === existingwill always be true for at least 1 path.- Instead I had success with:
const minimalPaths = uniquePaths.filter((path) =>
// false to filter out parent dirs
// true for unique dirs
uniquePaths.every((existing) => // If this is parent to any other dir (hence every instead of some), return false
path === existing || !existing.startsWith(path + '/') //if equal, pass check
// if startswith, eject with false
)
);
* With that, it should be possible to create all the dirs in a single replace_files call, something like: const pathsToCreate = minNecessaryPaths.filter((path) => !existingDirPaths.has(path));
if (pathsToCreate.length) {
try {
await this.createDirectory(collectionUuid, pathsToCreate, showErrors, preserveVersion);
} catch (error) {
console.error("Error creating directory", collectionUuid, error);
}
}
- I would add a
preserveVersion = trueto replaceFiles and createDirectory (in case we use that elsewhere and want it to save versions by default) and pass false from createMinNecessaryDirs or add another param there and pass false from the caller.
With this it should only tick up the version once, and only make a single call to create dirs
- I think it would be good to add a few unit tests to getMinNecessaryPaths
Updated by Lisa Knox 8 months ago
19378-folder-upload @ b73816a4dc649c7c79ba07636c530e9b6a17d1e3
developer-run-tests-services-workbench2: #1543
These suggestions were all implemented.
Also addressed is the bug where dropping a file + a folder would only upload the file, it now works as expected, uploading everything.
There is now a line in the form to indicate that empty folders will not be uploaded, which is a limitation imposed by the browser. If we want to support creating empty folders in the future, it would be trivial, but it's not likely that we will.
Updated by Lisa Knox 8 months ago
- Status changed from In Progress to Resolved
Applied in changeset arvados|ef636fbbdeb49eecfaee61b659261ece7985d689.
Updated by Brett Smith 8 months ago
- Status changed from Resolved to In Progress
This merge is not passing tests and that needs to be addressed promptly. run-tests-services-workbench2-integration: #581
Running: collection.cy.js (4 of 24)
Collection panel tests
✓ allows to download mountain duck config for a collection (6258ms)
✓ attempts to use a preexisting name creating or updating a collection (10182ms)
✓ uses the property editor (from edit dialog) with vocabulary terms (5047ms)
✓ uses the editor (from details panel) with vocabulary terms (6666ms)
✓ shows collection by URL (10040ms)
✓ renames a file using valid names (67749ms)
✓ renames a file to a different directory (22803ms)
✓ shows collection owner (6912ms)
✓ tries to rename a file with illegal names (9628ms)
✓ can correctly display old versions (3010ms)
✓ views & edits storage classes data (5537ms)
✓ moves a collection to a different project (7889ms)
✓ automatically updates the collection UI contents without using the Refresh button (4963ms)
✓ makes a copy of an existing collection (6556ms)
✓ uses the collection version browser to view a previous version (14141ms)
✓ copies selected files into new collection (7992ms)
✓ copies selected files into existing collection (9805ms)
✓ copies selected files into separate collections (13551ms)
✓ moves selected files into new collection (8201ms)
✓ moves selected files into existing collection (9317ms)
✓ moves selected files into separate collections (12746ms)
✓ creates new collection with properties on home project (8150ms)
✓ shows responsible person for collection if available (4389ms)
file upload
✓ uploads a file and checks the collection UI to be fresh (9691ms)
1) uploads and maintains nested folder structure
✓ allows to cancel running upload (5346ms)
✓ allows to cancel single file from the running upload (5962ms)
✓ allows to cancel all files from the running upload (8690ms)
✓ displays the correct breadcrumbs after moving a collection to trash (10959ms)
28 passing (5m)
1 failing
1) Collection panel tests
file upload
uploads and maintains nested folder structure:
AssertionError: Timed out retrying after 4000ms: Expected to find element: `[data-cy=upload-button]`, but never found it.
at Context.eval (webpack://arvados-workbench-2/./cypress/e2e/collection.cy.js:1257:19)
(Results)
┌────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Tests: 29 │
│ Passing: 28 │
│ Failing: 1 │
│ Pending: 0 │
│ Skipped: 0 │
│ Screenshots: 1 │
│ Video: false │
│ Duration: 5 minutes, 17 seconds │
│ Spec Ran: collection.cy.js │
└────────────────────────────────────────────────────────────────────────────────────────────────┘
Updated by Lisa Knox 8 months ago
19378-test-fix @ 8c77cf55162641f6583c030f1e7b38a92f121223
developer-run-tests-services-workbench2: #1544
One of the tests that was updated in #22793 got overwritten in the merge with main, now fixed.
Updated by Brett Smith 8 months ago
Lisa Knox wrote in #note-48:
Please run all of developer-run-tests. This job does not run the Workbench integration tests, which was a contributing factor to being in this situation in the first place.
One of the tests that was updated in #22793 got overwritten in the merge with main, now fixed.
I'm not sure I follow the history here. If I run git log -p origin/19378-test-fix -- services/workbench2/cypress/e2e/collection.cy.js, the three most recent commits are:
- 96569b43db932face7e73eb1b05ff04d3159d504 adds the completely new test, with the code that fails
- ef636fbbdeb49eecfaee61b659261ece7985d689 merges the branch to main, apparently without changes to this specific file
- 8c77cf55162641f6583c030f1e7b38a92f121223 changes the new test's code
When I hear "overwritten in the merge to main," what I imagine is that there was a merge conflict at some point and it got resolved incorrectly. In a case like that, I would expect to see a diff in a merge commit that shows the bad resolution. There's no diff like that here, so it seems like I'm misunderstanding what you mean. At what point in the development process did the code in your fix commit get overwritten?
Updated by Brett Smith 8 months ago
Discussed at standup:
- I misunderstood the job, as shown in the console output it does run integration tests as well.
- This is basically a classic "conflict between parallel branches" development problem. One factor that makes this one feel avoidable is the fact that the conflicting branch #22793 got merged 14 days prior. We will add a review checklist item about this.
This is good to merge, thanks.
Updated by Lisa Knox 8 months ago
- Status changed from In Progress to Resolved
Applied in changeset arvados|74e3210fed5057a2a182ff5b7b553104016c8129.