mirror of
https://github.com/System-End/cdn.git
synced 2026-04-19 20:55:10 +00:00
add multiple file uploads
This commit is contained in:
parent
ef79dabe59
commit
54f8733c02
3 changed files with 43 additions and 32 deletions
|
|
@ -37,7 +37,7 @@ class Components::Uploads::Index < Components::Base
|
||||||
|
|
||||||
label(for: "dropzone-file-input", class: "btn btn-primary", style: "cursor: pointer;") do
|
label(for: "dropzone-file-input", class: "btn btn-primary", style: "cursor: pointer;") do
|
||||||
render Primer::Beta::Octicon.new(icon: :upload, mr: 1)
|
render Primer::Beta::Octicon.new(icon: :upload, mr: 1)
|
||||||
plain "Upload File"
|
plain "Upload Files"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -101,7 +101,7 @@ class Components::Uploads::Index < Components::Base
|
||||||
|
|
||||||
def dropzone_form
|
def dropzone_form
|
||||||
form_with url: uploads_path, method: :post, multipart: true, data: { dropzone_form: true } do
|
form_with url: uploads_path, method: :post, multipart: true, data: { dropzone_form: true } do
|
||||||
input(type: "file", name: "file", id: "dropzone-file-input", data: { dropzone_input: true }, style: "display: none;")
|
input(type: "file", name: "files[]", id: "dropzone-file-input", multiple: true, data: { dropzone_input: true }, style: "display: none;")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -15,28 +15,38 @@ class UploadsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
uploaded_file = params[:file]
|
uploaded_files = Array(params[:files]).reject(&:blank?)
|
||||||
|
|
||||||
if uploaded_file.blank?
|
if uploaded_files.empty?
|
||||||
redirect_to uploads_path, alert: "Please select a file to upload."
|
redirect_to uploads_path, alert: "Please select at least one file to upload."
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
blob = ActiveStorage::Blob.create_and_upload!(
|
success_count = 0
|
||||||
io: uploaded_file.tempfile,
|
errors = []
|
||||||
filename: uploaded_file.original_filename,
|
|
||||||
content_type: uploaded_file.content_type
|
|
||||||
)
|
|
||||||
|
|
||||||
@upload = current_user.uploads.create!(
|
uploaded_files.each do |uploaded_file|
|
||||||
blob: blob,
|
blob = ActiveStorage::Blob.create_and_upload!(
|
||||||
provenance: :web
|
io: uploaded_file.tempfile,
|
||||||
)
|
filename: uploaded_file.original_filename,
|
||||||
|
content_type: uploaded_file.content_type
|
||||||
|
)
|
||||||
|
|
||||||
redirect_to uploads_path, notice: "File uploaded successfully!"
|
current_user.uploads.create!(
|
||||||
rescue StandardError => e
|
blob: blob,
|
||||||
event = Sentry.capture_exception(e)
|
provenance: :web
|
||||||
redirect_to uploads_path, alert: "Upload failed: #{e.message} (Error ID: #{event&.event_id})"
|
)
|
||||||
|
success_count += 1
|
||||||
|
rescue StandardError => e
|
||||||
|
Sentry.capture_exception(e)
|
||||||
|
errors << "#{uploaded_file.original_filename}: #{e.message}"
|
||||||
|
end
|
||||||
|
|
||||||
|
if errors.any?
|
||||||
|
redirect_to uploads_path, alert: "#{success_count} file(s) uploaded. Errors: #{errors.join(', ')}"
|
||||||
|
else
|
||||||
|
redirect_to uploads_path, notice: "#{success_count} #{'file'.pluralize(success_count)} uploaded successfully!"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
|
|
@ -51,23 +61,25 @@ class UploadsController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def check_quota
|
def check_quota
|
||||||
uploaded_file = params[:file]
|
uploaded_files = Array(params[:files]).reject(&:blank?)
|
||||||
return if uploaded_file.blank? # Let create action handle missing file
|
return if uploaded_files.empty? # Let create action handle missing files
|
||||||
|
|
||||||
quota_service = QuotaService.new(current_user)
|
quota_service = QuotaService.new(current_user)
|
||||||
file_size = uploaded_file.size
|
|
||||||
policy = quota_service.current_policy
|
policy = quota_service.current_policy
|
||||||
|
total_size = uploaded_files.sum(&:size)
|
||||||
|
|
||||||
# Check per-file size limit
|
# Check per-file size limit for each file
|
||||||
if file_size > policy.max_file_size
|
uploaded_files.each do |uploaded_file|
|
||||||
redirect_to uploads_path, alert: "File size (#{ActiveSupport::NumberHelper.number_to_human_size(file_size)}) exceeds your limit of #{ActiveSupport::NumberHelper.number_to_human_size(policy.max_file_size)} per file."
|
if uploaded_file.size > policy.max_file_size
|
||||||
return
|
redirect_to uploads_path, alert: "File '#{uploaded_file.original_filename}' (#{ActiveSupport::NumberHelper.number_to_human_size(uploaded_file.size)}) exceeds your limit of #{ActiveSupport::NumberHelper.number_to_human_size(policy.max_file_size)} per file."
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Check if upload would exceed total storage quota
|
# Check if uploads would exceed total storage quota
|
||||||
unless quota_service.can_upload?(file_size)
|
unless quota_service.can_upload?(total_size)
|
||||||
usage = quota_service.current_usage
|
usage = quota_service.current_usage
|
||||||
redirect_to uploads_path, alert: "Uploading this file would exceed your storage quota. You're using #{ActiveSupport::NumberHelper.number_to_human_size(usage[:storage_used])} of #{ActiveSupport::NumberHelper.number_to_human_size(usage[:storage_limit])}."
|
redirect_to uploads_path, alert: "Uploading these files would exceed your storage quota. You're using #{ActiveSupport::NumberHelper.number_to_human_size(usage[:storage_used])} of #{ActiveSupport::NumberHelper.number_to_human_size(usage[:storage_limit])}."
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -22,10 +22,9 @@
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
|
|
||||||
// Handle file input change
|
// Handle file input change (supports multiple files)
|
||||||
fileInput.addEventListener("change", (e) => {
|
fileInput.addEventListener("change", (e) => {
|
||||||
const file = e.target.files[0];
|
if (e.target.files.length > 0) {
|
||||||
if (file) {
|
|
||||||
form.requestSubmit();
|
form.requestSubmit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -77,7 +76,7 @@
|
||||||
dropzone.classList.add("file-dropzone");
|
dropzone.classList.add("file-dropzone");
|
||||||
|
|
||||||
const title = document.createElement("h1");
|
const title = document.createElement("h1");
|
||||||
title.innerText = "Drop your file here";
|
title.innerText = "Drop your files here";
|
||||||
dropzone.appendChild(title);
|
dropzone.appendChild(title);
|
||||||
|
|
||||||
document.body.appendChild(dropzone);
|
document.body.appendChild(dropzone);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue