#1548 Documents upload in one step

This commit is contained in:
Karel Pičman 2024-09-19 15:48:08 +02:00
parent e0532a81b2
commit 8b1018b06f
5 changed files with 145 additions and 48 deletions

View File

@ -41,6 +41,17 @@ class DmsfUploadController < ApplicationController
def upload_files
uploaded_files = params[:dmsf_attachments]
# Commit
if params[:commit] == l(:label_dmsf_commit)
uploaded_files&.each do |key, uploaded_file|
upload = DmsfUpload.create_from_uploaded_attachment(@project, @folder, uploaded_file)
params[:committed_files][key][:disk_filename] = upload.disk_filename
params[:committed_files][key][:digest] = upload.digest
params[:committed_files][key][:tempfile_path] = upload.tempfile_path
end
commit_files
# Upload
else
@uploads = []
# standard file input uploads
uploaded_files&.each do |_, uploaded_file|
@ -49,6 +60,7 @@ class DmsfUploadController < ApplicationController
end
flash.now[:error] = "#{l(:label_attachment)} #{l('activerecord.errors.messages.invalid')}" if @uploads.empty?
end
end
# REST API and Redmine attachment form
def upload

View File

@ -68,6 +68,21 @@
</span>
<span class="dmsf_add_attachment add_attachment">
<%
if defined?(container) && container
project = container.project
folder = container.system_folder
else
project = @project
folder = @folder
end
project_or_folder = folder ? folder : project
files = []
project_or_folder.dmsf_files.visible.each do |dmsf_file|
rev = dmsf_file.last_revision
files << [dmsf_file.name, rev.major_version, rev.minor_version, rev.patch_version ] if rev
end
%>
<%= file_field_tag 'dmsf_attachments[dummy][file]',
id: nil,
class: 'file_selector',
@ -80,17 +95,19 @@
max_concurrent_uploads: Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
upload_path: dmsf_uploads_path(format: 'js'),
description_placeholder: l(:label_optional_description),
project: @project ? "#{@project.identifier}" : '',
project: project.identifier,
awf: awf,
dmsf_file_details_form: container ? controller.send( :render_to_string,
dmsf_file_details_form: controller.send(:render_to_string,
{ partial: 'dmsf_upload/upload_file',
locals: { upload: DmsfUpload.new(container.project, nil, nil), i: 0 } }) : nil
} %>
locals: { upload: DmsfUpload.new(project, folder, nil), i: 0 } }),
files: JSON.generate(files)
}
%>
</span>
<% if defined?(container) && container %>
<span class="dmsf-add-link">
<%= link_to l(:label_link_from),
new_dmsf_link_path(project_id: container.project.id, type: 'link_from', container: container.class.name),
new_dmsf_link_path(project_id: project.id, type: 'link_from', container: container.class.name),
title: l(:title_create_link), class: 'icon icon-add file_selector', remote: true %>
</span>
<% end %>

View File

@ -18,6 +18,8 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
%>
<% heads_for_wiki_formatter %>
<%= render partial: '/dmsf/path',
locals: { folder: @folder, filename: nil, title: l(:label_attachment_new) } %>
@ -25,13 +27,14 @@
<%= form_tag({ controller: 'dmsf_upload', action: 'upload_files', id: @project, folder_id: @folder },
{ id: 'uploadform', multipart: true }) do %>
<div class="box tabular">
<span class="dmsf-uploader">
<%= render partial: 'dmsf_upload/form',
locals: { multiple: true, container: nil, description: true, awf: false } %>
</span>
</div>
<div class="form-actions">
<%= submit_tag l(:label_upload), data: { cy: 'button__submit--dmsf-upload--project' }, class: 'button-positive' %>
<%= submit_tag l(:label_upload), data: { cy: 'button__submit--dmsf-upload--project' }, class: 'button-positive',
id: "dmsf-upload-button" %>
<%= submit_tag l(:label_dmsf_commit), data: { cy: 'button__submit--dmsf-commit--project' },
class: 'button-positive' %>
</div>
<% end %>

View File

@ -42,7 +42,7 @@
<% end %>
<div class="form-actions">
<%= submit_tag l(:label_dmsf_commit),
data: { cy: 'button__submit__upload-file--project' },
data: { cy: 'button__submit__commit-file--project' },
class: 'button-positive',
onclick: "$('#ajax-indicator').show();" %>
</div>

View File

@ -60,6 +60,63 @@ function humanFileSize(bytes) {
return (u ? bytes.toFixed(2) + ' ' : bytes) + ' KMGTPEZY'[u] + 'B';
}
/* Increase version */
function increaseVersion(version, max) {
let res;
if (version >= 0) {
if ((version + 1) < max) {
res = ++version;
} else {
res = version;
}
} else {
if (-(version - 1) < 90 /* 'Z' */) {
res = --version;
} else
res = version;
}
if (res < 0) {
res = String.fromCharCode(-res); // -65 => 'A'
}
return res;
}
/* Get next version */
function getNextVersion(filename, files) {
for(let i = 0; i < files.length; i++) {
if(filename === files[i][0]) {
if(files[i][3] && (files[i][3] >= 0)) {
return [files[i][1], files[i][2], increaseVersion(files[i][3], 1000)];
}
if(files[i][2] && (files[i][2] >= 0)) {
return [files[i][1], increaseVersion(files[i][2], 1000), null];
}
return [increaseVersion(files[i][1], 100), null, null];
}
}
return [0, 1, null];
}
/* Replace selected version */
function replaceVersion(detailsForm, attachmentId, name, version) {
let index = detailsForm.search('id="committed_files_' + attachmentId + '_version_' + name + '"');
if (index != -1) {
let str = detailsForm.substring(index);
// Remove the original selection
str = str.replace('selected="selected" ', '');
// Select new version
if (version != null) {
str = str.replace('<option value="' + version + '">' + version + '</option>', '<option selected="selected" value="' + version + '">' + version + '</option>');
}
else {
let c = String.fromCharCode(160); // &nbsp;
str = str.replace('<option value="">' + c + '</option>', '<option selected="selected" value="">' + c + '</option>');
}
detailsForm = detailsForm.substring(0, index) + str;
}
return detailsForm;
}
function dmsfAddFile(inputEl, file, eagerUpload) {
let attachments = $('#dmsf_attachments_fields');
@ -90,26 +147,38 @@ function dmsfAddFile(inputEl, file, eagerUpload) {
// Details
let detailsForm = $(inputEl).data('dmsf-file-details-form');
if(detailsForm) {
let detailsDiv = $('<div>').attr({id: 'dmsf_attachments_details_' + attachmentId});
let detailsArrow = $('<a>');
detailsArrow.attr({href: '#', 'class': 'icon-only icon-sorted-asc', title: 'Details'});
detailsArrow.attr(
{
onclick: "$('#dmsf_attachments_details_" + attachmentId + "').toggle();" +
"$(this).toggleClass('icon-sorted-asc');$(this).toggleClass('icon-sorted-desc');" +
"$('#dmsf-upload-button').hide();" +
"return false;"
});
// Index
detailsForm = detailsForm.replace(/\[0\]/g, '[' + attachmentId + ']');
detailsForm = detailsForm.replace(/_0/g, '_' + attachmentId);
// Name
detailsForm = detailsForm.replace('id="committed_files_' + attachmentId + '_name" value=""',
'id="committed_files_' + attachmentId + '_name" value="' + file.name + '"');
// Title
detailsForm = detailsForm.replace('id="committed_files_' + attachmentId + '_title"',
'id="committed_files_' + attachmentId + '_title" value = "' + filenameToTitle(file.name) + '"');
// Size
detailsForm = detailsForm.replace('id="committed_files_' + attachmentId + '_size"',
'id="committed_files_' + attachmentId + '_size" value = "' + humanFileSize(file.size) + '"');
// Mime type
detailsForm = detailsForm.replace('id="committed_files_' + attachmentId + '_mime_type"',
'id="committed_files_' + attachmentId + '_mime_type" value = "' + file.type + '"');
// Version
let version = getNextVersion(file.name, $(inputEl).data('files'));
detailsForm = replaceVersion(detailsForm, attachmentId, 'patch', version[2]);
detailsForm = replaceVersion(detailsForm, attachmentId, 'minor', version[1]);
detailsForm = replaceVersion(detailsForm, attachmentId, 'major', version[0]);
detailsDiv.append(detailsForm);
detailsDiv.hide();
@ -117,10 +186,6 @@ function dmsfAddFile(inputEl, file, eagerUpload) {
attachments.append(fileSpan);
attachments.append(detailsDiv);
}
else {
attachments.append(fileSpan);
}
}
else{
fileSpan.append(iconDel.click(dmsfRemoveFileLbl));
attachments.append(fileSpan);