Uppy.js Uploader System

This document explains how to use the generalized uppy.js uploader system in the Heatwave application.

Overview

The uppy.js uploader system provides a modern, drag-and-drop file upload interface using Stimulus controllers. It's designed to be reusable across different parts of the application with sensible defaults.

Components

1. Stimulus Controller (app/javascript/controllers/uppy_uploader_controller.js)

The main Stimulus controller that handles uppy.js initialization and event management.

Key Features:

  • Lazy-loaded (only loads when needed)
  • Configurable via data attributes
  • Automatic CSRF token handling
  • Real-time progress and error feedback
  • Custom event dispatching

2. Reusable Partial (app/views/shared/_uppy_uploader.html.erb)

A flexible partial that can be used anywhere in the application.

Parameters:

  • endpoint: Upload endpoint URL
  • max_files: Maximum number of files (default: 10)
  • max_file_size: Maximum file size in bytes (default: 10MB)
  • allowed_file_types: Array of allowed MIME types (default: ['image/*'])
  • field_name: Form field name for uploads (default: 'file')
  • hidden_field_name: Hidden field name for file IDs (default: 'upload_ids')
  • auto_proceed: Auto-upload files when selected (default: false)
  • height: Uploader height in pixels (default: 400)
  • note: User instruction text
  • submit_button_text: Submit button text
  • form_url: Form submission URL
  • form_method: HTTP method (default: :post)
  • resource_name: Form resource name

3. Helper Methods (app/helpers/uppy_uploader_helper.rb)

Convenient helper methods for common upload scenarios.

Usage Examples

Basic Usage

<%= uppy_uploader(
  endpoint: upload_images_path,
  max_files: 5,
  note: 'Upload up to 5 images'
) do %>
  <%= link_to 'Cancel', some_path, class: 'btn btn-secondary' %>
<% end %>

RMA Image Uploads

<%= rma_image_uploader(@rma) do %>
  <%= link_to 'Cancel', rmas_path, class: 'btn btn-secondary' %>
<% end %>

File Uploads (Images + PDFs)

<%= file_uploader(
  max_files: 3,
  allowed_file_types: ['image/*', 'application/pdf'],
  note: 'Upload images or PDFs'
) do %>
  <%= link_to 'Cancel', documents_path, class: 'btn btn-secondary' %>
<% end %>

Video Uploads

<%= video_uploader(
  max_file_size: 200 * 1024 * 1024, # 200MB
  note: 'Upload video files up to 200MB'
) do %>
  <%= link_to 'Cancel', videos_path, class: 'btn btn-secondary' %>
<% end %>

Controller Integration

The uploader automatically handles file uploads and stores file IDs in a hidden field. Your controller should process these IDs:

def create
  file_ids = JSON.parse(params[:upload_ids]) rescue []
  
  file_ids.each do |file_id|
    # Process each uploaded file
    file_details = ImageKitFactory.client.get_file_details(file_id: file_id)
    # Create your model records here
  end
end

Customization

Custom Data Attributes

You can pass additional data attributes to the uploader:

<div data-controller="uppy-uploader"
     data-uppy-uploader-endpoint-value="<%= custom_upload_path %>"
     data-uppy-uploader-max-files-value="20"
     data-uppy-uploader-custom-value="some-value">
  <!-- uploader content -->
</div>

Custom Event Handling

The controller dispatches custom events that you can listen to:

document.addEventListener('uppy-uploader:uploadComplete', (event) => {
  const { fileIds, result } = event.detail
  console.log('Upload complete:', fileIds)
})

Benefits

  1. Lazy Loading: Uppy.js only loads when the uploader is present on the page
  2. Reusable: One controller handles all upload scenarios
  3. Configurable: Extensive customization options via data attributes
  4. Modern UI: Drag-and-drop interface with progress indicators
  5. Error Handling: Comprehensive error messages and recovery
  6. Accessibility: Built-in accessibility features from uppy.js
  7. Mobile Friendly: Works well on mobile devices

Migration from Old System

To migrate from the old file upload system:

  1. Replace inline JavaScript with the Stimulus controller
  2. Use the helper methods for common scenarios
  3. Update your controller to handle the new file ID format
  4. Test thoroughly with different file types and sizes

Troubleshooting

Common Issues

  1. Files not uploading: Check the endpoint URL and CSRF token
  2. File type errors: Verify allowed_file_types includes your file types
  3. Size limit errors: Check max_file_size value (in bytes)
  4. Controller not loading: Ensure the Stimulus controller is properly registered

Debug Mode

The controller runs in debug mode by default. Check the browser console for detailed logs.