Project

General

Profile

Actions

Feature #19378

closed

Can select folder to recursively upload all the files to Collection

Added by Peter Amstutz over 3 years ago. Updated 6 months ago.

Status:
Resolved
Priority:
Normal
Assigned To:
Category:
Workbench2
Target version:
Story points:
3.0
Release relationship:
Auto

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


Subtasks 1 (0 open1 closed)

Task #20333: Review 19378-folder-uploadResolvedStephen Smith07/17/2025Actions

Related issues 2 (1 open1 closed)

Related to Arvados - Bug #16170: Uploading of folder structure into collection is not workingNewActions
Is duplicate of Arvados Workbench 2 - Support #15197: [Data operation] Folders uploadDuplicateActions
Actions #1

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-08-31 sprint to 2022-09-14 sprint
Actions #2

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-09-14 sprint to 2022-09-28 sprint
Actions #3

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-09-28 sprint to 2022-10-26 sprint
Actions #4

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-10-26 sprint to 2022-11-09 sprint
Actions #5

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-11-09 sprint to 2022-11-23 sprint
Actions #6

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-11-23 sprint to 2022-12-07 Sprint
Actions #7

Updated by Peter Amstutz over 3 years ago

  • Is duplicate of Support #15197: [Data operation] Folders upload added
Actions #8

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-12-07 Sprint to 2022-12-21 Sprint
Actions #9

Updated by Peter Amstutz over 3 years ago

  • Target version changed from 2022-12-21 Sprint to 2023-01-18 sprint
Actions #10

Updated by Peter Amstutz over 3 years ago

  • Story points set to 3.0
Actions #11

Updated by Peter Amstutz about 3 years ago

  • Target version changed from 2023-01-18 sprint to 2023-02-01 sprint
Actions #12

Updated by Peter Amstutz about 3 years ago

  • Release set to 59
  • Target version deleted (2023-02-01 sprint)
Actions #13

Updated by Peter Amstutz about 3 years ago

  • Target version set to To be scheduled
Actions #14

Updated by Peter Amstutz almost 3 years ago

  • Target version changed from To be scheduled to Development 2023-04-26 sprint
Actions #15

Updated by Peter Amstutz almost 3 years ago

  • Assigned To set to Stephen Smith
Actions #16

Updated by Peter Amstutz almost 3 years ago

  • Status changed from New to Duplicate
Actions #17

Updated by Peter Amstutz almost 3 years ago

  • Status changed from Duplicate to New
Actions #18

Updated by Peter Amstutz almost 3 years ago

  • Target version changed from Development 2023-04-26 sprint to Development 2023-05-10 sprint
Actions #19

Updated by Peter Amstutz almost 3 years ago

  • Target version changed from Development 2023-05-10 sprint to To be scheduled
Actions #20

Updated by Peter Amstutz over 2 years ago

  • Target version changed from To be scheduled to Development 2023-09-13 sprint
Actions #21

Updated by Peter Amstutz over 2 years ago

  • Target version changed from Development 2023-09-13 sprint to Development 2023-09-27 sprint
Actions #22

Updated by Peter Amstutz over 2 years ago

  • Target version changed from Development 2023-09-27 sprint to To be scheduled
Actions #23

Updated by Peter Amstutz about 2 years ago

  • Target version changed from To be scheduled to Future
Actions #24

Updated by Peter Amstutz 12 months ago

  • Target version changed from Future to Development 2025-04-30
Actions #25

Updated by Peter Amstutz 12 months ago

  • Related to Bug #16170: Uploading of folder structure into collection is not working added
Actions #26

Updated by Peter Amstutz 12 months ago

  • Assigned To deleted (Stephen Smith)
Actions #27

Updated by Peter Amstutz 11 months ago

  • Target version changed from Development 2025-04-30 to Development 2025-05-14
Actions #28

Updated by Peter Amstutz 11 months ago

  • Target version changed from Development 2025-05-14 to Development 2025-04-30
Actions #29

Updated by Peter Amstutz 11 months ago

  • Description updated (diff)
Actions #30

Updated by Peter Amstutz 11 months ago

  • Assigned To set to Lisa Knox
Actions #31

Updated by Stephen Smith 11 months ago

  • Description updated (diff)
Actions #32

Updated by Peter Amstutz 11 months ago

  • Target version changed from Development 2025-04-30 to Development 2025-05-14
Actions #33

Updated by Peter Amstutz 11 months ago

  • Target version changed from Development 2025-05-14 to Development 2025-05-28
Actions #34

Updated by Peter Amstutz 11 months ago

  • Target version changed from Development 2025-05-28 to Development 2025-06-25
Actions #35

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.

Actions #36

Updated by Peter Amstutz 10 months ago

  • Target version changed from Development 2025-06-25 to Development 2025-07-09
Actions #37

Updated by Peter Amstutz 10 months ago

  • Target version changed from Development 2025-07-09 to Development 2025-07-23
Actions #38

Updated by Peter Amstutz 10 months ago

  • Target version changed from Development 2025-07-23 to Development 2025-08-06
Actions #39

Updated by Peter Amstutz 10 months ago

  • Target version changed from Development 2025-08-06 to Future
Actions #40

Updated by Brett Smith 9 months ago

  • Target version changed from Future to Development 2025-07-09
  • Status changed from New to In Progress
Actions #41

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.
Notes:
  • 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
Actions #42

Updated by Brett Smith 9 months ago

  • Target version changed from Development 2025-07-09 to Development 2025-07-23
Actions #43

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 getMinNecessaryPaths doesn't actually filter out parent folder paths, since uniquePaths.some((existing) => path === existing will always be true because path is an anumeration of uniquePaths so path === existing will 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 = true to 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
Actions #44

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.

Actions #45

Updated by Stephen Smith 8 months ago

This looks great! lgtm!

Actions #46

Updated by Lisa Knox 8 months ago

  • Status changed from In Progress to Resolved
Actions #47

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                                                                 │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
Actions #48

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.

Actions #49

Updated by Brett Smith 8 months ago

Lisa Knox wrote in #note-48:

developer-run-tests-services-workbench2: #1544

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:

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?

Actions #50

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.

Actions #51

Updated by Lisa Knox 8 months ago

  • Status changed from In Progress to Resolved
Actions #52

Updated by Brett Smith 6 months ago

  • Release set to 79
Actions

Also available in: Atom PDF