#48 look and feel

This commit is contained in:
Karel Picman 2017-08-03 12:55:37 +02:00
parent abbaea2692
commit 5a1c0ec2d2
33 changed files with 348 additions and 178 deletions

View File

@ -87,7 +87,7 @@ class DmsfLinksController < ApplicationController
@dmsf_link.project_id = params[:dmsf_link][:project_id] @dmsf_link.project_id = params[:dmsf_link][:project_id]
@dmsf_link.dmsf_folder_id = params[:dmsf_link][:dmsf_folder_id] @dmsf_link.dmsf_folder_id = params[:dmsf_link][:dmsf_folder_id]
else else
# An issue link # A container link
@dmsf_link.project_id = -1 @dmsf_link.project_id = -1
@dmsf_link.dmsf_folder_id = nil @dmsf_link.dmsf_folder_id = nil
end end

View File

@ -24,11 +24,11 @@ class DmsfUploadController < ApplicationController
menu_item :dmsf menu_item :dmsf
before_action :find_project, :except => [:upload, :delete_dmsf_attachment] before_action :find_project, :except => [:upload, :delete_dmsf_attachment, :delete_dmsf_link_attachment]
before_action :authorize, :except => [:upload, :delete_dmsf_attachment] before_action :authorize, :except => [:upload, :delete_dmsf_attachment, :delete_dmsf_link_attachment]
before_action :authorize_global, :only => [:upload, :delete_dmsf_attachment] before_action :authorize_global, :only => [:upload, :delete_dmsf_attachment, :delete_dmsf_link_attachment]
before_action :find_folder, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment] before_action :find_folder, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment, :delete_dmsf_link_attachment]
before_action :permissions, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment] before_action :permissions, :except => [:upload_file, :upload, :commit, :delete_dmsf_attachment, :delete_dmsf_link_attachment]
helper :all helper :all
helper :dmsf_workflows helper :dmsf_workflows
@ -75,7 +75,7 @@ class DmsfUploadController < ApplicationController
end end
end end
# REST API document upload # REST API and Redmine attachment form
def upload def upload
unless request.content_type == 'application/octet-stream' unless request.content_type == 'application/octet-stream'
render :nothing => true, :status => 406 render :nothing => true, :status => 406
@ -130,6 +130,13 @@ class DmsfUploadController < ApplicationController
render_404 render_404
end end
def delete_dmsf_link_attachment
link = DmsfLink.find(params[:id])
link.destroy
rescue ActiveRecord::RecordNotFound
render_404
end
private private
def commit_files_internal(commited_files) def commit_files_internal(commited_files)

View File

@ -215,7 +215,7 @@
<% end %> <% end %>
<% if (@file_manipulation_allowed && !@locked_for_user && !@system_folder) %> <% if (@file_manipulation_allowed && !@locked_for_user && !@system_folder) %>
<%= render(:partial => 'dmsf_upload/multi_upload') %> <%= render(:partial => 'dmsf_upload/multi_upload', :local => { :lbl => true }) %>
<% end %> <% end %>
<% unless @system_folder %> <% unless @system_folder %>

View File

@ -35,12 +35,12 @@
:dmsf_file_revision_id => file.last_revision.id), :dmsf_file_revision_id => file.last_revision.id),
:title => l(:title_waiting_for_approval), :title => l(:title_waiting_for_approval),
:remote => true, :remote => true,
:class => 'icon icon-wf-waiting') %> :class => "icon-only icon-wf-waiting") %>
<% else %> <% else %>
<span class="icon"></span> <span class="icon-only"></span>
<% end %> <% end %>
<% else %> <% else %>
<span class="icon"></span> <span class="icon-only"></span>
<% end %> <% end %>
<% when DmsfWorkflow::STATE_ASSIGNED %> <% when DmsfWorkflow::STATE_ASSIGNED %>
<% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) && wf %> <% if User.current && (file.last_revision.dmsf_workflow_assigned_by == User.current.id) && wf %>
@ -49,12 +49,12 @@
:id => file.last_revision.dmsf_workflow_id, :id => file.last_revision.dmsf_workflow_id,
:dmsf_file_revision_id => file.last_revision.id), :dmsf_file_revision_id => file.last_revision.id),
:title => l(:label_dmsf_wokflow_action_start), :title => l(:label_dmsf_wokflow_action_start),
:class => 'icon icon-wf-assigned') %> :class => 'icon-only icon-wf-assigned') %>
<% else %> <% else %>
<span class="icon"></span> <span class="icon"></span>
<% end %> <% end %>
<% when DmsfWorkflow::STATE_APPROVED, DmsfWorkflow::STATE_REJECTED %> <% when DmsfWorkflow::STATE_APPROVED, DmsfWorkflow::STATE_REJECTED %>
<span class="icon"></span> <span class="icon-only"></span>
<% else %> <% else %>
<% if workflows_available %> <% if workflows_available %>
<%= link_to('', <%= link_to('',
@ -69,9 +69,9 @@
:dmsf_file_revision_id => file.last_revision.id), :dmsf_file_revision_id => file.last_revision.id),
:title => l(:label_dmsf_wokflow_action_assign), :title => l(:label_dmsf_wokflow_action_assign),
:remote => true, :remote => true,
:class => 'icon icon-wf-none') %> :class => 'icon-only icon-wf-none') %>
<% else %> <% else %>
<span class="icon"></span> <span class="icon-only"></span>
<% end %> <% end %>
<% end %> <% end %>
<% end %> <% end %>

View File

@ -78,7 +78,8 @@
<div class="box"> <div class="box">
<p> <p>
<%= label_tag('file_upload', l(:label_new_content)) %> <%= label_tag('file_upload', l(:label_new_content)) %>
<%= render :partial => 'dmsf_upload/form', :locals => { :multiple => false, :container => nil } %> <%= render :partial => 'dmsf_upload/form',
:locals => { :multiple => false, :container => nil, :description => false, :awf => false } %>
</p> </p>
</div> </div>
<p> <p>

View File

@ -24,17 +24,21 @@
<% if defined?(thumbnails) && thumbnails %> <% if defined?(thumbnails) && thumbnails %>
<% images = links.map{ |x| x[0] }.select(&:image?) %> <% images = links.map{ |x| x[0] }.select(&:image?) %>
<% if images.any? %> <% if images.any? %>
<div class="thumbnails"> <% if link_to # Redmine classic %>
<div class="thumbnails">
<% end %>
<% images.each do |file| %> <% images.each do |file| %>
<div> <div>
<% if link_to # Redmine classic %> <% if link_to # Redmine classic %>
<%= link_to image_tag(dmsf_thumbnail_path(file)), view_dmsf_file_path(file), :alt => file.title %> <%= link_to image_tag(dmsf_thumbnail_path(file)), view_dmsf_file_path(file), :alt => file.title %>
<% else # jQuery gallery %> <% else # jQuery gallery %>
<%= image_tag(dmsf_thumbnail_path(file), <%= image_tag(dmsf_thumbnail_path(file),
{ :'data-fullsrc' => view_dmsf_file_path(file), :alt => file.title }) %> { :'data-fullsrc' => view_dmsf_file_path(file), :alt => file.title }) %>
<% end %> <% end %>
</div> </div>
<% end %> <% end %>
</div> <% if link_to # Redmine classic %>
</div>
<% end %>
<% end %> <% end %>
<% end %> <% end %>

View File

@ -20,7 +20,7 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
%> %>
var linksSpan = $("#dmsf_links_fields"); var linksSpan = $("#dmsf_links_attachments_fields");
var linkId = "<%= @dmsf_link.id %>"; var linkId = "<%= @dmsf_link.id %>";
var linkName = "<%= @dmsf_link.name %>"; var linkName = "<%= @dmsf_link.name %>";
var title = "<%= l(:label_dmsf_wokflow_action_assign) %>"; var title = "<%= l(:label_dmsf_wokflow_action_assign) %>";
@ -35,4 +35,4 @@ var awf = false;
<% end %> <% end %>
<% end %> <% end %>
dmsfAddLink(linksSpan, linkId, linkName, title, project, awf); dmsfAddLink(linksSpan, linkId, linkName, title, project, awf, <%= !defined?(EasyExtensions) %>);

View File

@ -21,30 +21,56 @@
%> %>
<span id="dmsf_attachments_fields"> <span id="dmsf_attachments_fields">
<% if defined?(container) && container && container.saved_dmsf_attachments.present? %> <% if defined?(container) && container && container.saved_dmsf_attachments.present? %>
<% container.saved_dmsf_attachments.each_with_index do |attachment, i| %> <% container.saved_dmsf_attachments.each_with_index do |attachment, i| %>
<span id="dmsf_attachments_p<%= i %>"> <span id="dmsf_attachments_p<%= i %>", class="attachment">
<%= text_field_tag("dmsf_attachments[p#{i}][filename]", attachment.filename, :class => 'filename') + <%= hidden_field_tag "dmsf_attachments[p#{i}][token]", "#{attachment.token}" %>
text_field_tag("dmsf_attachments[p#{i}][description]", attachment.description, :maxlength => 255, <%= text_field_tag("dmsf_attachments[p#{i}][filename]", attachment.filename, :class => 'filename') %>
:placeholder => l(:label_optional_description), :class => 'description') + <%= text_field_tag("dmsf_attachments[p#{i}][description]", attachment.description, :maxlength => 255,
link_to('&nbsp;'.html_safe, dmsf_attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'), :placeholder => l(:label_optional_description), :class => 'description') if description %>
:method => 'delete', :remote => true, :class => 'remove-upload icon icon-del') %> <%= link_to('', dmsf_attachment_path(attachment, :attachment_id => "p#{i}", :format => 'js'),
<%= hidden_field_tag "dmsf_attachments[p#{i}][token]", "#{attachment.token}" %> :method => 'delete', :remote => true, :class => 'remove-upload icon-only icon-del') %>
<% wf = container.saved_dmsf_attachments_wfs[attachment.id] %> <% wf = container.saved_dmsf_attachments_wfs[attachment.id] %>
<% if wf %> <% if wf %>
<a href="javascript:void(0);" title="<%= l(:title_assigned) %>" class="icon icon-wf-assigned"></a> <a href="javascript:void(0);" title="<%= l(:title_assigned) %>" class="icon-only icon-wf-assigned"></a>
<%= hidden_field_tag("dmsf_attachments_wfs[p#{i}]", wf.id) if wf %> <%= hidden_field_tag("dmsf_attachments_wfs[p#{i}]", wf.id) if wf %>
<% else %> <% else %>
<%= link_to('', assign_dmsf_workflow_path(:id => container.project.id, :project_id => container.project.id, <%= link_to('', assign_dmsf_workflow_path(:id => container.project.id, :project_id => container.project.id,
:attachment_id => i + 1), :title => l(:label_dmsf_wokflow_action_assign), :attachment_id => i + 1), :title => l(:label_dmsf_wokflow_action_assign),
:remote => true, :class => 'icon icon-wf-none') %> :remote => true, :class => 'icon-only icon-wf-none') %>
<% end %> <% end %>
</span> </span>
<% end %>
<% end %> <% end %>
</span>
<span id="dmsf_links_attachments_fields">
<% if defined?(container) && container && container.saved_dmsf_links.present? %>
<% container.saved_dmsf_links.each_with_index do |dmsf_link, index| %>
<span id="dmsf_links_attachments_<%= index %>", class="attachment">
<input name="dmsf_links[<%= index %>]" value="<%= dmsf_link.id %>" type="hidden">
<input type="text" class='filename readonly' value="<%= dmsf_link.name %>">
<%= link_to('', dmsf_link_attachment_path(dmsf_link, :link_id => "#{index}", :format => 'js'),
:method => 'delete', :remote => true, :class => 'remove-upload icon-only icon-del') %>
<% wf = container.saved_dmsf_links_wfs[dmsf_link.id] %>
<% if wf %>
<a href="javascript:void(0);" title="<%= l(:title_assigned) %>" class="icon-only icon-wf-assigned"></a>
<%= hidden_field_tag("dmsf_links_wfs[#{dmsf_link.id}]", wf.id) if wf %>
<% else %>
<%= render(:partial => 'dmsf_files/approval_workflow_button',
:locals => {:file => dmsf_link.target_file,
:file_approval_allowed => User.current.allowed_to?(:file_approval, dmsf_link.target_file.project),
:workflows_available => DmsfWorkflow.where(
['project_id = ? OR project_id IS NULL', dmsf_link.target_file.project_id]).exists?,
:project => dmsf_link.target_file.project, :wf => wf, :dmsf_link_id => dmsf_link.id }) %>
<% end %>
</span>
<% end %>
<% end %> <% end %>
</span> </span>
<span class="dmsf_add_attachment">
<%= file_field_tag 'dmsf_attachments[dummy][file]', <span class="dmsf_add_attachment add_attachment">
<%= file_field_tag 'dmsf_attachments[dummy][file]',
:id => nil, :id => nil,
:class => 'file_selector', :class => 'file_selector',
:multiple => multiple, :multiple => multiple,
@ -56,40 +82,18 @@
:max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i, :max_concurrent_uploads => Redmine::Configuration['max_concurrent_ajax_uploads'].to_i,
:upload_path => dmsf_uploads_path(:format => 'js'), :upload_path => dmsf_uploads_path(:format => 'js'),
:description_placeholder => l(:label_optional_description), :description_placeholder => l(:label_optional_description),
:project => "#{@project.identifier}" :project => "#{@project.identifier}",
:description => description,
:awf => awf
} %> } %>
(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
</span> </span>
<% if container %> <% if defined?(container) && container %>
<br/> <span class="dmsf_add_link">
<span id="dmsf_links_fields"> <%= link_to l(:label_link_from),
<% if container.saved_dmsf_links.present? %> new_dmsf_link_path(:project_id => container.project.id, :type => 'link_from', :container => container.class.name),
<% container.saved_dmsf_links.each_with_index do |dmsf_link, index| %> :title => l(:title_create_link), :class => 'icon icon-add file_selector', :remote => true %>
<span id="dmsf_links_<%= index %>"> </span>
<input name="dmsf_links[<%= index %>]" value="<%= dmsf_link.id %>" type="hidden">
<input type="text" class='filename readonly' value="<%= dmsf_link.name %>">
<a href="#" class="remove-upload icon icon-del" onclick="$(this).parent('span').remove();return false;">&nbsp;</a>
<% wf = container.saved_dmsf_links_wfs[dmsf_link.id] %>
<% if wf %>
<a href="javascript:void(0);" title="<%= l(:title_assigned) %>" class="icon icon-wf-assigned"></a>
<%= hidden_field_tag("dmsf_links_wfs[#{dmsf_link.id}]", wf.id) if wf %>
<% else %>
<%= render(:partial => 'dmsf_files/approval_workflow_button',
:locals => {:file => dmsf_link.target_file,
:file_approval_allowed => User.current.allowed_to?(:file_approval, dmsf_link.target_file.project),
:workflows_available => DmsfWorkflow.where(
['project_id = ? OR project_id IS NULL', dmsf_link.target_file.project]).exists?,
:project => dmsf_link.target_file.project, :wf => wf, :dmsf_link_id => dmsf_link.id }) %>
<% end %>
<br/>
</span>
<% end %>
<% end %>
</span>
<span class="dmsf_add_link">
<%= link_to l(:label_link_from),
new_dmsf_link_path(:project_id => container.project.id, :type => 'link_from', :container => 'issue'),
:title => l(:title_create_link), :class => 'icon icon-add', :remote => true %>
</span>
<% end %> <% end %>
<span class="info">
(<%= l(:label_max_size) %>: <%= number_to_human_size(Setting.attachment_max_size.to_i.kilobytes) %>)
</span>

View File

@ -38,7 +38,8 @@
:id => 'uploadform', :method => :post, :multipart => true) do %> :id => 'uploadform', :method => :post, :multipart => true) do %>
<div id="dmsf_uploader"> <div id="dmsf_uploader">
<span class="dmsf_uploader"> <span class="dmsf_uploader">
<%= render :partial => 'dmsf_upload/form', :locals => { :multiple => true, :container => nil } %> <%= render :partial => 'dmsf_upload/form',
:locals => { :multiple => true, :container => nil, :description => true, :awf => false } %>
</span> </span>
<%= submit_tag l(:label_upload) %> <%= submit_tag l(:label_upload) %>
</div> </div>

View File

@ -0,0 +1 @@
$('#dmsf_links_attachments_<%= j params[:link_id] %>').remove();

View File

@ -26,7 +26,7 @@ var fileSpan = $('#dmsf_attachments_<%= j params[:attachment_id] %>');
alert("<%= escape_javascript @attachment.errors.full_messages.join(', ') %>"); alert("<%= escape_javascript @attachment.errors.full_messages.join(', ') %>");
<% else %> <% else %>
$('<input>', { type: 'hidden', name: 'dmsf_attachments[<%= j params[:attachment_id] %>][token]' } ).val('<%= j @attachment.token %>').appendTo(fileSpan); $('<input>', { type: 'hidden', name: 'dmsf_attachments[<%= j params[:attachment_id] %>][token]' } ).val('<%= j @attachment.token %>').appendTo(fileSpan);
fileSpan.find('a.remove-upload') fileSpan.find('a.dmsf-remove-upload')
.attr({ .attr({
"data-remote": true, "data-remote": true,
"data-method": 'delete', "data-method": 'delete',

View File

@ -24,24 +24,24 @@ function dmsfAddLink(linksSpan, linkId, linkName, title, project, awf) {
if (linksSpan.children().length < 10) { if (linksSpan.children().length < 10) {
var nextLinkId = dmsfAddLink.nextLinkId++; var nextLinkId = dmsfAddLink.nextLinkId++;
var linkSpan = $('<span>', { id: 'dmsf_links_' + nextLinkId }); var linkSpan = $('<span>', { id: 'dmsf_links_attachments_' + nextLinkId, 'class': 'attachment' });
var iconDel = $('<a>').attr({href: '#', 'class': 'remove-upload icon-only icon-del'});
var inputId = $('<input>', {type: 'hidden', name: 'dmsf_links[' + nextLinkId + ']'}).val(linkId);
var inputName = $('<input>', {type: 'text', class: 'filename readonly'}).val(linkName);
linkSpan.append( linkSpan.append(inputId);
"<input name='dmsf_links[" + nextLinkId + "]' value='" + linkId + "' type='hidden'>", linkSpan.append(inputName);
"<input type='text' class='filename readonly' value='" + linkName + "'>", linkSpan.append(iconDel.click(dmsfRemoveFileLbl));
$('<a>&nbsp;</a>').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile)
);
if(awf) { if(awf) {
linkSpan.append($('<a>&nbsp;</a>').attr({ var iconWf = $('<a>').attr({href: "/dmsf_workflows/" + project + "/assign?dmsf_link_id=" + linkId,
href: "/dmsf_workflows/" + project + "/assign?dmsf_link_id=" + linkId, 'class': 'icon-only icon-wf-none', 'data-remote': 'true', 'title': title});
'class': 'icon icon-wf-none', 'data-remote': 'true', 'title': title
})); linkSpan.append(iconWf);
} }
linkSpan.append("<br/>"); linksSpan.append(linkSpan);
linkSpan.appendTo(linksSpan);
} }
} }
@ -52,37 +52,41 @@ function dmsfAddFile(inputEl, file, eagerUpload) {
if ($('#dmsf_attachments_fields').children().length < 10) { if ($('#dmsf_attachments_fields').children().length < 10) {
var attachmentId = dmsfAddFile.nextAttachmentId++; var attachmentId = dmsfAddFile.nextAttachmentId++;
var fileSpan = $('<span>', { id: 'dmsf_attachments_' + attachmentId }); var fileSpan = $('<span>', { id: 'dmsf_attachments_' + attachmentId, 'class': 'attachment' });
var iconDel = $('<a>').attr({href: '#', 'class': 'remove-upload icon-only icon-del'}).toggle(!eagerUpload);
var fileName = $('<input>', {type: 'text', 'class': 'filename readonly',
name: 'dmsf_attachments[' + attachmentId + '][filename]', readonly: 'readonly'}).val(file.name);
if($(inputEl).attr('multiple') == 'multiple') { if($(inputEl).attr('multiple') == 'multiple') {
fileSpan.append(
$('<input>', { fileSpan.append(fileName);
type: 'text',
'class': 'filename readonly', if($(inputEl).data('description')) {
name: 'dmsf_attachments[' + attachmentId + '][filename]',
readonly: 'readonly' var description = $('<input>', {type: 'text', 'class': 'description',
}).val(file.name), name: 'dmsf_attachments[' + attachmentId + '][description]', maxlength: 255,
$('<input>', {
type: 'text',
'class': 'description',
name: 'dmsf_attachments[' + attachmentId + '][description]',
maxlength: 255,
placeholder: $(inputEl).data('description-placeholder') placeholder: $(inputEl).data('description-placeholder')
}).toggle(!eagerUpload), }).toggle(!eagerUpload);
$('<a>&nbsp;</a>').attr({href: "#", 'class': 'remove-upload icon icon-del'}).click(dmsfRemoveFile).toggle(!eagerUpload),
$('<a>&nbsp;</a>').attr({href: "/dmsf_workflows/" + $(inputEl).attr('data-project') + "/assign?attachment_id=" + attachmentId, fileSpan.append(description);
'class': 'icon icon-wf-none', 'data-remote': 'true'}) }
).appendTo('#dmsf_attachments_fields');
fileSpan.append(iconDel.click(dmsfRemoveFileLbl));
if($(inputEl).data('awf')) {
var iconWf = $('<a>').attr({href: '/dmsf_workflows/' + $(inputEl).attr(
'data-project') + "/assign?attachment_id=" + attachmentId, 'class': 'icon-only icon-wf-none',
'data-remote': 'true'});
fileSpan.append(iconWf);
}
$('#dmsf_attachments_fields').append(fileSpan);
} }
else{ else{
fileSpan.append( fileSpan.append(fileName);
$('<input>', { $('#dmsf_attachments_fields').append(fileSpan);
type: 'text',
'class': 'filename readonly',
name: 'dmsf_attachments[' + attachmentId + '][filename]',
readonly: 'readonly'
}).val(file.name)
).appendTo('#dmsf_attachments_fields');
$('#dmsf_file_revision_name').val(file.name); $('#dmsf_file_revision_name').val(file.name);
} }
@ -150,8 +154,17 @@ function dmsfAjaxUpload(file, attachmentId, fileSpan, inputEl) {
dmsfAjaxUpload.uploading = 0; dmsfAjaxUpload.uploading = 0;
function dmsfRemoveFile() { function dmsfRemoveFileLbl() {
$(this).parent('span').remove(); $(this).parent('span').remove();
return false;
}
function dmsfRemoveFile() {
$(this).parent('span').parent('span').remove();
return false; return false;
} }
@ -189,7 +202,9 @@ function dmsfUploadBlob(blob, uploadUrl, attachmentId, options) {
} }
function dmsfAddInputFiles(inputEl) { function dmsfAddInputFiles(inputEl) {
var clearedFileInput = $(inputEl).clone().val(''); var clearedFileInput = $(inputEl).clone().val('');
var addFileSpan = $('.dmsf_add_attachment');
if ($.ajaxSettings.xhr().upload && inputEl.files) { if ($.ajaxSettings.xhr().upload && inputEl.files) {
// upload files using ajax // upload files using ajax
@ -199,16 +214,22 @@ function dmsfAddInputFiles(inputEl) {
// browser not supporting the file API, upload on form submission // browser not supporting the file API, upload on form submission
var attachmentId; var attachmentId;
var aFilename = inputEl.value.split(/\/|\\/); var aFilename = inputEl.value.split(/\/|\\/);
attachmentId = dmsfAddFile(inputEl, { name: aFilename[ aFilename.length - 1 ] }, false); attachmentId = dmsfAddFile(inputEl, {name: aFilename[aFilename.length - 1]}, false);
if (attachmentId) { if (attachmentId) {
$(inputEl).attr({ name: 'dmsf_attachments[' + attachmentId + '][file]', style: 'display:none;' }).appendTo('#dmsf_attachments_' + attachmentId); $(inputEl).attr({name: 'dmsf_attachments[' + attachmentId + '][file]', style: 'display:none;'}).appendTo(
'#dmsf_attachments_' + attachmentId);
} }
} }
if($(inputEl).attr('multiple') == 'multiple') if ($(inputEl).attr('multiple') == 'multiple') {
clearedFileInput.insertAfter('#dmsf_attachments_fields');
else clearedFileInput.val('');
$('.dmsf_add_attachment').toggle(); addFileSpan.prepend(clearedFileInput);
}
else {
addFileSpan.hide();
}
} }
function dmsfUploadAndAttachFiles(files, inputEl) { function dmsfUploadAndAttachFiles(files, inputEl) {
@ -223,7 +244,9 @@ function dmsfUploadAndAttachFiles(files, inputEl) {
if (sizeExceeded) { if (sizeExceeded) {
window.alert(maxFileSizeExceeded); window.alert(maxFileSizeExceeded);
} else { } else {
$.each(files, function() {dmsfAddFile(inputEl, this, true);}); $.each(files, function() {
dmsfAddFile(inputEl, this, true);
});
} }
} }

View File

@ -302,8 +302,8 @@ div.dmsf_revision_inner_box .attribute .label {
/* DMSF file upload */ /* DMSF file upload */
.dmsf_uploader{ .dmsf_uploader{
padding:6px; padding:10px;
margin-bottom: 10px; margin-bottom: 20px;
background-color:#f6f6f6; background-color:#f6f6f6;
color:#505050; color:#505050;
line-height:1.5em; line-height:1.5em;
@ -312,6 +312,21 @@ div.dmsf_revision_inner_box .attribute .label {
border-radius: 3px; border-radius: 3px;
min-height: 50px; min-height: 50px;
display: block; display: block;
overflow: hidden;
}
.dmsf_add_link{
display: block;
float: right;
margin-top: 10px;
margin-bottom: 10px;
}
.dmsf_add_file{
display: block;
float: left;
margin-top: 10px;
margin-bottom: 10px;
} }
#dmsf_attachments_fields input.description {margin-left:4px; width:340px;} #dmsf_attachments_fields input.description {margin-left:4px; width:340px;}
@ -321,5 +336,5 @@ div.dmsf_revision_inner_box .attribute .label {
#dmsf_attachments_fields .ajax-loading input.filename {background:url(../../../images/loading.gif) no-repeat 0px 50%;} #dmsf_attachments_fields .ajax-loading input.filename {background:url(../../../images/loading.gif) no-repeat 0px 50%;}
#dmsf_attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; } #dmsf_attachments_fields div.ui-progressbar { width: 100px; height:14px; margin: 2px 0 -5px 8px; display: inline-block; }
#dmsf_links_fields span {display:block; white-space:nowrap;} #dmsf_links_attachments_fields span {display:block; white-space:nowrap;}
#dmsf_links_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../../../images/link.png) no-repeat 1px 50%; padding-left:18px;} #dmsf_links_attachments_fields input.filename {border:0; height:1.8em; width:250px; color:#555; background-color:inherit; background:url(../../../images/link.png) no-repeat 1px 50%; padding-left:18px;}

View File

@ -366,3 +366,6 @@ cs:
note_dmsf_act_as_attachable: Umožní přikládat dokumenty k objektům např. úkolům. note_dmsf_act_as_attachable: Umožní přikládat dokumenty k objektům např. úkolům.
label_user_search_add: Vyhledej uživatele pro přidání label_user_search_add: Vyhledej uživatele pro přidání
label_dmsf_attachments: DMS přílohy
label_basic_attachments: Souborové přílohy

View File

@ -363,3 +363,6 @@ de:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Anhänge
label_basic_attachments: Dateianhängen

View File

@ -366,3 +366,6 @@ en:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ es:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ fr:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -365,3 +365,6 @@ hu:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ it: # Italian strings thx 2 Matteo Arceci!
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ ja:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ pl:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ pt-BR:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ ru:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ sl:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ zh-TW:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -366,3 +366,6 @@ zh:
note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues. note_dmsf_act_as_attachable: Allows to attach documents to objects e.g. issues.
label_user_search_add: Search for user to add label_user_search_add: Search for user to add
label_dmsf_attachments: DMS Attachments
label_basic_attachments: Basic Attachments

View File

@ -68,6 +68,7 @@ if Redmine::Plugin.installed? :redmine_dmsf
post '/projects/:id/dmsf/commit', :controller => 'dmsf_upload', :action => 'commit' post '/projects/:id/dmsf/commit', :controller => 'dmsf_upload', :action => 'commit'
match 'dmsf_uploads', :to => 'dmsf_upload#upload', :via => :post match 'dmsf_uploads', :to => 'dmsf_upload#upload', :via => :post
delete '/dmsf/attachments/:id/delete', :to => 'dmsf_upload#delete_dmsf_attachment', :as => 'dmsf_attachment' delete '/dmsf/attachments/:id/delete', :to => 'dmsf_upload#delete_dmsf_attachment', :as => 'dmsf_attachment'
delete '/dmsf/link_attachments/:id/delete', :to => 'dmsf_upload#delete_dmsf_link_attachment', :as => 'dmsf_link_attachment'
# #
# dmsf_files controller # dmsf_files controller

View File

@ -87,7 +87,8 @@ Redmine::Plugin.register :redmine_dmsf do
:dmsf_folder_permissions => [:new, :append, :autocomplete_for_user] } :dmsf_folder_permissions => [:new, :append, :autocomplete_for_user] }
permission :file_manipulation, permission :file_manipulation,
{ :dmsf_files => [:create_revision, :lock, :unlock, :delete_revision, :notify_activate, :notify_deactivate, :restore], { :dmsf_files => [:create_revision, :lock, :unlock, :delete_revision, :notify_activate, :notify_deactivate, :restore],
:dmsf_upload => [:upload_files, :upload_file, :upload, :commit_files, :commit, :delete_dmsf_attachment], :dmsf_upload => [:upload_files, :upload_file, :upload, :commit_files, :commit, :delete_dmsf_attachment,
:delete_dmsf_link_attachment],
:dmsf_links => [:new, :create, :destroy, :restore, :autocomplete_for_project, :autocomplete_for_folder] } :dmsf_links => [:new, :create, :destroy, :restore, :autocomplete_for_project, :autocomplete_for_folder] }
permission :file_delete, permission :file_delete,
{ :dmsf => [:trash, :delete_entries], { :dmsf => [:trash, :delete_entries],

View File

@ -58,6 +58,7 @@ module RedmineDmsf
if context.is_a?(Hash) if context.is_a?(Hash)
issue = context[:issue] issue = context[:issue]
params = context[:params] params = context[:params]
User.current.pref.update_attribute :dmsf_attachments_upload_choice, params[:dmsf_attachments_upload_choice]
issue.save_dmsf_attachments(params[:dmsf_attachments]) issue.save_dmsf_attachments(params[:dmsf_attachments])
issue.save_dmsf_links(params[:dmsf_links]) issue.save_dmsf_links(params[:dmsf_links])
issue.save_dmsf_attachments_wfs(params[:dmsf_attachments_wfs], params[:dmsf_attachments]) issue.save_dmsf_attachments_wfs(params[:dmsf_attachments_wfs], params[:dmsf_attachments])

View File

@ -26,11 +26,32 @@ module RedmineDmsf
def view_issues_form_details_bottom(context={}) def view_issues_form_details_bottom(context={})
return if defined?(EasyExtensions) return if defined?(EasyExtensions)
context[:container] = context[:issue]
attach_documents_form(context) attach_documents_form(context)
end end
def view_issues_edit_notes_bottom(context={}) def view_issues_edit_notes_bottom(context={})
attach_documents_form(context) html = ''
# Radio buttons
if allowed_to_attach_documents(context[:container])
html << '<p>'
html << '<label class="inline">'
html << radio_button_tag('dmsf_attachments_upload_choice', 'Attachments',
User.current.pref.dmsf_attachments_upload_choice == 'Attachments',
onchange: "$('.attachments-container').parent().show(); $('.dmsf_uploader').parent().hide(); return false;")
html << l(:label_basic_attachments)
html << '</label>'
html << '<label class="inline">'
html << radio_button_tag('dmsf_attachments_upload_choice', 'DMSF',
User.current.pref.dmsf_attachments_upload_choice == 'DMSF',
onchange: "$('.attachments-container').parent().hide(); $('.dmsf_uploader').parent().show(); return false;")
html << l(:label_dmsf_attachments)
html << '</label>'
html << '</p>'
end
# Upload form
html.html_safe + attach_documents_form(context, false,
defined?(EasyExtensions) && EasySetting.value('attachment_description'))
end end
def view_issues_show_description_bottom(context={}) def view_issues_show_description_bottom(context={})
@ -40,23 +61,42 @@ module RedmineDmsf
def view_issues_show_attachments_bottom(context={}) def view_issues_show_attachments_bottom(context={})
unless context[:options][:only_mails].present? unless context[:options][:only_mails].present?
show_attached_documents(context[:container], context[:controller]) show_attached_documents(context[:container], context[:controller], context[:attachments])
end end
end end
def view_issues_dms_attachments(context={})
'yes' if get_links(context[:container]).any?
end
def view_issues_show_thumbnails(context={}) def view_issues_show_thumbnails(context={})
show_thumbnails(context[:container], context[:controller])
end
def view_issues_dms_thumbnails(context={})
unless context[:options][:only_mails].present? unless context[:options][:only_mails].present?
show_thumbnails(context[:container], context[:controller]) links = get_links(context[:container])
if links.present? && Setting.thumbnails_enabled?
images = links.map{ |x| x[0] }.select(&:image?)
return 'yes' if images.any?
end
end end
end end
private private
def allowed_to_attach_documents(container)
container &&
User.current.allowed_to?(:file_manipulation, container.project) &&
Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] &&
(container.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS)
end
def get_links(container) def get_links(container)
links = []
if defined?(container.dmsf_files) && User.current.allowed_to?(:view_dmsf_files, container.project) && if defined?(container.dmsf_files) && User.current.allowed_to?(:view_dmsf_files, container.project) &&
Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] && Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] &&
(container.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS) (container.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS)
links = []
for dmsf_file in container.dmsf_files for dmsf_file in container.dmsf_files
if dmsf_file.last_revision if dmsf_file.last_revision
links << [dmsf_file, nil, dmsf_file.created_at] links << [dmsf_file, nil, dmsf_file.created_at]
@ -69,8 +109,9 @@ module RedmineDmsf
end end
end end
# Sort by 'create_at' # Sort by 'create_at'
links.sort{ |x, y| x[2] <=> y[2] } links.sort!{ |x, y| x[2] <=> y[2] }
end end
links
end end
def show_thumbnails(container, controller) def show_thumbnails(container, controller)
@ -83,18 +124,21 @@ module RedmineDmsf
end end
end end
def attach_documents_form(context) def attach_documents_form(context, label=true, description=true)
if context.is_a?(Hash) && context[:issue] if context.is_a?(Hash) && context[:container]
# Add Dmsf upload form # Add Dmsf upload form
issue = context[:issue] container = context[:container]
if User.current.allowed_to?(:file_manipulation, issue.project) && if allowed_to_attach_documents(container)
Setting.plugin_redmine_dmsf['dmsf_act_as_attachable'] && html = "<p class=\"#{(User.current.pref[:dmsf_attachments_upload_choice] == 'Attachments') ? 'hol' : ''}\">"
(issue.project.dmsf_act_as_attachable == Project::ATTACHABLE_DMS_AND_ATTACHMENTS) if label
html = '<p>'
html << "<label>#{l(:label_document_plural)}</label>" html << "<label>#{l(:label_document_plural)}</label>"
html << "<span class=\"dmsf_uploader\">" html << "<span class=\"attachments-container dmsf_uploader\">"
else
html << "<span class=\"attachments-container dmsf_uploader\" style=\"border: 2px dashed #dfccaf; background: none;\">"
end
html << context[:controller].send(:render_to_string, html << context[:controller].send(:render_to_string,
{ :partial => 'dmsf_upload/form', :locals => { :container => issue, :multiple => true }}) { :partial => 'dmsf_upload/form',
:locals => { :container => container, :multiple => true, :description => description, :awf => true }})
html << '</span>' html << '</span>'
html << '</p>' html << '</p>'
html.html_safe html.html_safe
@ -102,7 +146,7 @@ module RedmineDmsf
end end
end end
def show_attached_documents(container, controller) def show_attached_documents(container, controller, attachments=nil)
# Add list of attached documents # Add list of attached documents
links = get_links(container) links = get_links(container)
if links.present? if links.present?
@ -110,18 +154,23 @@ module RedmineDmsf
controller.send(:render_to_string, {:partial => 'dmsf_files/links', controller.send(:render_to_string, {:partial => 'dmsf_files/links',
:locals => { :links => links, :thumbnails => Setting.thumbnails_enabled? }}) :locals => { :links => links, :thumbnails => Setting.thumbnails_enabled? }})
else else
attachment_rows(links, container, controller) attachment_rows(links, container, controller, attachments)
end end
end end
end end
def attachment_rows(links, issue, controller) def attachment_rows(links, issue, controller, attachments)
html = '<tbody>' if links.any?
links.each do |dmsf_file, link, create_at| html = '<tbody>'
html << attachment_row(dmsf_file, link, issue, controller) if attachments.any?
html << "<tr><th colspan=\"4\">#{l(:label_dmsf_attachments)} (#{links.count})</th></tr>"
end
links.each do |dmsf_file, link, create_at|
html << attachment_row(dmsf_file, link, issue, controller)
end
html << '</tbody>'
html.html_safe
end end
html << '</tbody>'
html.html_safe
end end
def attachment_row(dmsf_file, link, issue, controller) def attachment_row(dmsf_file, link, issue, controller)

View File

@ -18,22 +18,41 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
module DmsfUserPreference module RedmineDmsf
def self.included(base) module Patches
base.send(:include, InstanceMethods) module UserPreference
end
module InstanceMethods def self.included(base)
base.send(:include, InstanceMethods)
end
def dmsf_tree_view module InstanceMethods
self[:dmsf_tree_view] || '1'
end def dmsf_tree_view
self[:dmsf_tree_view] || '1'
end
def dmsf_tree_view=(value)
self[:dmsf_tree_view] = value
end
def dmsf_attachments_upload_choice
self[:dmsf_attachments_upload_choice] || 'DMSF'
end
def dmsf_attachments_upload_choice=(value)
self[:dmsf_attachments_upload_choice] = value
end
end
def dmsf_tree_view=(value)
self[:dmsf_tree_view] = value
end end
end end
end end
UserPreference.send(:include, DmsfUserPreference) # Apply patch
Rails.configuration.to_prepare do
unless UserPreference.included_modules.include?(RedmineDmsf::Patches::UserPreference)
UserPreference.send(:include, RedmineDmsf::Patches::UserPreference)
end
end

View File

@ -21,7 +21,8 @@
require File.expand_path('../../test_helper', __FILE__) require File.expand_path('../../test_helper', __FILE__)
class DmsfFolderPermissionsControllerTest < RedmineDmsf::Test::TestCase class DmsfFolderPermissionsControllerTest < RedmineDmsf::Test::TestCase
fixtures :users, :dmsf_folders, :projects, :roles, :members, :member_roles, :dmsf_folder_permissions fixtures :users, :dmsf_folders, :projects, :roles, :members, :member_roles, :dmsf_folder_permissions,
:email_addresses
def setup def setup
@project1 = Project.find_by_id 1 @project1 = Project.find_by_id 1