web-components icon indicating copy to clipboard operation
web-components copied to clipboard

[upload] Modularization

Open jouni opened this issue 8 years ago • 15 comments

Disclaimer: I’ve not thought this all through properly, but this is my current rough idea

Split the current vaadin-upload element into modules. When combined/connected together, they should produce the same feature set as the current element, but offer more customization options and ways to integrate those parts in other use cases.

Modules (element names are just initial ideas):

  • vaadin-file-provider: for selecting files (either dropping on it or opening the OS dialog)

    • This would have the accept criteria features (single or multiple files, what file types and sizes are accepted, etc.)
    • The developer could customize the button and the drop target (and have it separated from the upload progress list)
    • Would fire an event when the user provides some files, and that event would contain the FileList array
    • This element could possibly be used for other use cases as well (in some editor for example, for selecting the files to open for editing)
  • vaadin-uploader: only handles the data communication, sending data to the server and firing events about the upload progress. Not sure if there should be one element per file (that is my gut feeling), or if one element can handle multiple uploads.

    • Would accept a FileList array, and could be configured to start uploads automatically, or leave them pending for manual start.
    • This element could be used separately if someone would like to provide an alternative way of providing the uploaded files than through the vaadin-file-provider UI.
  • vaadin-uploader-list: showing the status of files being uploaded, and allowing the end user to start/stop individual uploads (or all uploads at once).

    • Not exactly sure how the APIs should work here, but this would somehow be connected to the uploader (maybe this element could wrap the uploader element?)

jouni avatar Jun 30 '17 13:06 jouni

@jouni Looks pretty good. Something that may be worth looking into would be having two versions of vaadin-uploader one with the current ajax method and the other using the HTML5 File API setup.

I can work on a technical document for what I am thinking and how it all works together. I put them together all the time for work. I'm hoping to cover a lot of the feature set that is missing in the existing codebase as well. Let me know if you have any concerns or comments.

stramel avatar Jul 01 '17 05:07 stramel

@jouni @manolo @platosha PTAL Hopefully this will be a good starting point.

These are my thoughts on the refactor and how I envision it coming together. I am completely open to suggestions and comments.

While thinking about this, I have taken into consideration @jouni's thoughts and the Feature Backlog (#23).

Components

  • vaadin-upload: Alias for the current implementation built on top of the new design

  • vaadin-upload-(behavior|mixin): Holds the common properties and functionality

    • maxFileSize: The max file size allowed upload
    • accept: The accepted file types
    • fileSizeBase: Base that is used to calculate the filesize
    • capture: Capture type
    • clearOnComplete: Clear file list on completion
    • preventReload: Prevents reload during upload
    • required: Required input
    • invalid: Invalid State
  • vaadin-multiple-upload: For selecting files and acceptance criteria

    • Implements the vaadin-upload-behavior
    • files: The files queued for upload
    • maxFiles: The max file count
    • maxFilesReached: The max files reached
  • vaadin-single-upload: For selecting a file and allowing re-upload of a file. Also controls acceptance criteria

    • Implements the vaadin-upload-behavior
    • file: The file queued for upload
  • vaadin-uploader-(behavior|mixin): Common functionality for API uploaders

    • fallback: Provides a fallback upload strategy
    • files: All files
    • url: The upload target
    • method: The upload method
    • params: The upload query params
    • headers: The upload headers
    • timeout: The upload timeout
    • auto: Auto-uploads queued files
    • retryOnError: Auto Retry on errors
    • withCredentials: Add the withCredentials flag to the upload
    • cancel(): Cancels the upload
    • abort(): Cancels the upload and removes the file
    • uploadFiles(): Start queued files for upload
    • retry(): Retry a failed upload
  • vaddin-file-uploader: Uses the HTML5 File API

    • Implements vaadin-uploader-behavior
    • chunkSize: The size of bytes of each uploaded chunk of data
    • concurrentUploads: Number of concurrent uploads
    • prioritizeStartAndEnd: Prioritize the first and last chunks of file
    • testChunks: Test each chunk to see it already exists
    • pause(): Pause the upload
    • resume(): Resume the upload
  • vaadin-ajax-uploader: Uses XHR

    • Implements vaadin-uploader-behavior
  • vaadin-localstorage-uploader: Stores the files uploaded into the localstorage

    • files: All files
    • path: The path to store images at
  • vaadin-file-list: Displays a list of file items

    • files: All files queued and uploaded to display
  • vaadin-file-item: List item for displaying status and controlling the file's upload

    • file: File metadata, upload status and progress information
  • vaadin-file-preview: Renders a preview of the file that was uploaded or queued for upload

    • file: The file to render a preview for
  • vaadin-dropzone: Handles the drag-n-drop of file(s)

    • target: The target upload to handle the drag-n-drop
    • Has a slot so it can wrap existing content
    • Can handle pre-drop type and count validation
    • Can handle drop size validation

Basic Examples

Current Implementation (Basic Usage)

We could alias this as vaadin-upload with some minimal customization.

<vaadin-dropzone target="upload">
  <vaadin-ajax-uploader files="{{files}}"></vaadin-ajax-uploader>
  <vaadin-multiple-upload id="upload" files="{{files}}">
    <paper-button>UPLOAD FILES</paper-button>
  </vaadin-multiple-upload>
  <span>
    <iron-icon icon="vaadin:upload"></iron-icon>
    Drop Files here...
  </span>
  <vaadin-file-list files="{{files}}">
    <template>
      <vaadin-file-item file="{{file}}"></vaadin-file-item>
    </template>
  </vaadin-file-list>
</vaadin-dropzone>

Custom Dropzone

<vaadin-dropzone target="upload"></vaadin-dropzone>
<vaadin-ajax-uploader files="{{files}}"></vaadin-ajax-uploader>
<vaadin-multiple-upload id="upload" files="{{files}}">
  <paper-button>UPLOAD FILES</paper-button>
</vaadin-multiple-upload>
<span>
  <iron-icon icon="vaadin:upload"></iron-icon>
  Drop Files here...
</span>
<vaadin-file-list files="{{files}}">
  <template>
    <vaadin-file-item file="{{file}}"></vaadin-file-item>
  </template>
</vaadin-file-list>

HTML5 File API w/ fallback

<vaadin-dropzone target="upload">
  <vaadin-file-uploader files="{{files}}" fallback="ajax"></vaadin-file-uploader>
  <vaadin-ajax-uploader files="{{files}}" id="ajax"></vaadin-ajax-uploader>
  <vaadin-multiple-upload files="{{files}}">
    <paper-button>UPLOAD FILES</paper-button>
  </vaadin-multiple-upload>
  <span>
    <iron-icon icon="vaadin:upload"></iron-icon>
    Drop Files here...
  </span>
  <vaadin-file-list files="{{files}}">
    <template>
      <vaadin-file-item file="{{file}}"></vaadin-file-item>
    </template>
  </vaadin-file-list>
</vaadin-dropzone>

stramel avatar Sep 01 '17 06:09 stramel

Kudos, @stramel, for the proposal. I hope the team has some time to go through it asap. Would you be willing to build the first prototype for this, if we agree on the approach?

jouni avatar Sep 01 '17 12:09 jouni

Yeah, I could probably build out a prototype of it.

stramel avatar Sep 01 '17 13:09 stramel

I can’t find many things to point at, but here are some:

vaadin-upload-mixin – what is “capture”?

vaadin-upload alias – do we really need that, or should we just make users migrate to vaadin-multiple-upload? Or is there some difference between those?

uploader.cancel/abort/retry – do those target a single file in the list? Do we need “cancel/abort/retry all”?

localstorage-uploader.path mentions “images” – can’t we use localstorage for other file types?

vaadin-dropzone – Can I make it cover the entire viewport without wrapping other elements?

jouni avatar Sep 04 '17 18:09 jouni

Thanks for taking a look through it @jouni and providing some feedback.

vaadin-upload-mixin – what is “capture”?

capture is a pass-through to the input's capture attribute. (https://www.w3.org/TR/html-media-capture/#dom-htmlinputelement-capture)

vaadin-upload alias – do we really need that, or should we just make users migrate to vaadin-multiple-upload? Or is there some difference between those?

It isn't necessary. I just figured it would be a nice to have for an easy conversion to the next major change as well as providing an easy to use base interface. The difference between the two is that vaadin-upload recreates the existing vaadin-upload using the new components (ie. vaadin-multiple-upload, vaadin-dropzone, etc)

uploader.cancel/abort/retry – do those target a single file in the list? Do we need “cancel/abort/retry all”?

I would like to allow these to take a single file or multiple. Covert a single object to an array of 1 and accepting an array as well.

localstorage-uploader.path mentions “images” – can’t we use localstorage for other file types?

Yes, this could be any file type. Images are just the common type that I think of.

vaadin-dropzone – Can I make it cover the entire viewport without wrapping other elements?

Hmmm, that's an interesting thought. I think the only way to do that would be to take in a "drop-target" for handling drag-n-drop events and a "upload-target" for handling the upload of the dropped files. "drop-target" would allow you to specify something like document.body. "upload-target" would target the uploader.

stramel avatar Sep 04 '17 21:09 stramel

@jouni Did that answer your questions?

stramel avatar Sep 21 '17 19:09 stramel

@stramel, yes, seems pretty clear at this point. Let’s see after we have the first working pieces of the prototype, I’ll probably have more then :)

jouni avatar Sep 22 '17 06:09 jouni

Been a while since I updated this thread. I have a lot of the initial stuff working now. I need to do a few things before submitting for an initial review.

  • [x] Validation
  • [x] Single-upload
  • [x] Ajax configurability
  • [x] Clean up

Hoping to make good progress this weekend!

stramel avatar Nov 03 '17 20:11 stramel

Great to hear!

I did some snooping around, and the prototype is coming along in https://github.com/stramel/vaadin-upload/tree/ms/prototype-refactor, right?

Would you like someone to take a quick look at the work at this point? Just wondering if there are any obvious blockers that would slow things down more later on if not caught early?

jouni avatar Nov 06 '17 08:11 jouni

@jouni, yeah that's the branch. You can take a look if you would like and any feedback would be great!

I'm still trying to figure out the best way to handle some of the validations and hopefully clean up some aspects of it.

Hoping to have it out in a PR for everyone to review soon.

stramel avatar Nov 06 '17 14:11 stramel

For anyone who cares to take a preview of what I have, take a look at this PR. https://github.com/stramel/vaadin-upload/pull/1

Once I finish up a handful more things I will submit it over here. Just trying to get some initial feedback and gather my thoughts.

stramel avatar Nov 07 '17 07:11 stramel

The current implementation has a narrow use case. Splitting it apart as Michael Stramel has done would make it much more useful.

joelpop avatar Apr 22 '20 16:04 joelpop

Currently, what does the file-list do? I think it is just display-only, or does removing a file from the file-list remove it from the Receiver (I don't think it does anything).

It would also be nice if

  • clicking on a file in the file-list would generate an event on the server side
  • clicking on a file's X in the file-list would generate an event on the server side
  • the files could be removed from the file-list from the server side

joelpop avatar Apr 22 '20 19:04 joelpop

Also take into account plans for upload (and download) handlers described here: https://github.com/vaadin/platform/issues/7469

rolfsmeds avatar May 09 '25 19:05 rolfsmeds